From 00f5741f7f23e1c4f725752eede7da1e3061ec3a Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 13 Aug 2025 14:19:37 +0800 Subject: [PATCH 1/5] [Feat] (MG_Util/ShaderCompiler): add new item to ShaderCompileBits and implement it --- .../MG_Util/ShaderTranspiler/ShaderCompiler.cpp | 15 +++++++++++---- MobileGL/MG_Util/ShaderTranspiler/Types.h | 3 ++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp index d9f8e370..f98faf69 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp @@ -131,15 +131,22 @@ namespace MobileGL { const char* src[] = {sourceStr.data()}; tshader->setStrings(src, 1); tshader->setInvertY(true); - tshader->setEnvInput(glslang::EShSourceGlsl, lang, glslang::EShClientVulkan, 450); - tshader->setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_3); - tshader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_5); + if (attrib.flags & ShaderCompileBits::CompileForOpenGL) { + tshader->setEnvInput(glslang::EShSourceGlsl, lang, glslang::EShClientOpenGL, 450); + tshader->setEnvClient(glslang::EShClientOpenGL, glslang::EShTargetOpenGL_450); + tshader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_5); + } else { + tshader->setEnvInput(glslang::EShSourceGlsl, lang, glslang::EShClientVulkan, 450); + tshader->setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_3); + tshader->setEnvTarget(glslang::EShTargetSpv, + ((attrib.flags & ShaderCompileBits::EmitDiscardAsDemote) ? glslang::EShTargetSpv_1_6 : glslang::EShTargetSpv_1_5)); + } tshader->setAutoMapLocations(true); tshader->setAutoMapBindings(true); tshader->setEnvInputVulkanRulesRelaxed(); // using EXT_vulkan_glsl_relaxed for gl_VertexID and // gl_InstanceID? tshader->setGlobalUniformBlockName(GLOBAL_UBO_NAME); - if (!tshader->parse(&GetTBuiltInResourceInstance(), 150, ECoreProfile, + if (!tshader->parse(&GetTBuiltInResourceInstance(), 460, ECoreProfile, /*forceDefaultVersionAndProfile: */ false, /*forwardCompatible: */ true, EShMsgDefault)) { ResultInfo r; diff --git a/MobileGL/MG_Util/ShaderTranspiler/Types.h b/MobileGL/MG_Util/ShaderTranspiler/Types.h index 90761a66..dc0fc2c8 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/Types.h +++ b/MobileGL/MG_Util/ShaderTranspiler/Types.h @@ -9,7 +9,8 @@ namespace MobileGL { struct EmptyType {}; enum class ShaderCompileBits : Uint { - EmitDiscardAsDemote = 1 << 0, + CompileForOpenGL = 1 << 0, + EmitDiscardAsDemote = 1 << 1, }; struct ShaderAttrib { From 7f0e65f8c79566140150a12582c63697663073bb Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 13 Aug 2025 15:18:34 +0800 Subject: [PATCH 2/5] [Feat] (MG_Util/ShaderCompiler, MG_State/Program): reflect uniform location --- .../GLState/ProgramState/ProgramObject.cpp | 1 + .../GLState/ProgramState/ShaderObject.cpp | 36 +++++++++++++ .../GLState/ProgramState/ShaderObject.h | 4 +- MobileGL/MG_Test/Buffer/CMakeLists.txt | 1 + MobileGL/MG_Test/Program/CMakeLists.txt | 3 ++ MobileGL/MG_Test/Program/ProgramUtilTest.cpp | 50 +++++++++++++++++++ MobileGL/MG_Test/VertexArray/CMakeLists.txt | 1 + .../glslang/UniformTraverser.cpp | 39 +++++++++++++++ .../glslang/UniformTraverser.h | 24 +++++++++ 9 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp create mode 100644 MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.h diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp index db9bc49a..11d66352 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp @@ -63,6 +63,7 @@ namespace MobileGL { Vector>& ProgramObject::GetAttachedShaders() { return m_shaders; } + } // namespace GLState } // namespace MG_State } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp index f017bd1f..d90f40e9 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp @@ -1,6 +1,8 @@ #include "ShaderObject.h" #include +#include "MG_Util/ShaderTranspiler/glslang/UniformTraverser.h" + namespace MobileGL { namespace MG_State { namespace GLState { @@ -13,6 +15,10 @@ namespace MobileGL { } void ShaderObject::Compile() { + if (!DoReflection()) { + return; + } + using namespace MG_Util::ShaderTranspiler; ShaderAttrib attrib{ .shaderType = GetGLShaderTypeByMGLShaderStage(m_stage), @@ -36,6 +42,36 @@ namespace MobileGL { void ShaderObject::MarkAsDeleted() { m_deleteStatus = true; } + + bool ShaderObject::DoReflection() { + using namespace MG_Util::ShaderTranspiler; + ShaderAttrib attrib{ + .shaderType = GetGLShaderTypeByMGLShaderStage(m_stage), + .sourceStr = m_source, + .flags = ShaderCompileBits::CompileForOpenGL + }; + + auto result = ShaderCompiler::CompileShader(attrib); + if (!result) { + m_compileStatus = false; + m_infoLog = result.error().log; + + const std::string e = std::format("Shader compilation failed: \nerrc: {}\nmsg: {}\n", + result.error().errc, result.error().log); + return false; + } + + auto pShader = result.value(); + auto root = pShader->getIntermediate()->getTreeRoot(); + UniformTraverser traverser; + root->traverse(&traverser); + auto& symbols = traverser.GetCollectedSymbols(); + for (const auto& symbol : symbols) { + m_uniforms[symbol->getName().c_str()] = symbol->getQualifier().layoutLocation; + } + + return true; + } } // namespace GLState } // namespace MG_State } // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h index 0e2df307..60a0285d 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h @@ -68,12 +68,14 @@ namespace MobileGL { SharedPtr GetCompiledShader() const { return m_shader; } const String& GetInfoLog() const { return m_infoLog; } private: + bool DoReflection(); const Uint m_id = 0; const ShaderStage m_stage; String m_source; SharedPtr m_shader; - String m_infoLog; + UnorderedMap m_uniforms; + String m_infoLog; Bool m_deleteStatus = false; Bool m_compileStatus = false; }; diff --git a/MobileGL/MG_Test/Buffer/CMakeLists.txt b/MobileGL/MG_Test/Buffer/CMakeLists.txt index 80460495..2aa17712 100644 --- a/MobileGL/MG_Test/Buffer/CMakeLists.txt +++ b/MobileGL/MG_Test/Buffer/CMakeLists.txt @@ -36,6 +36,7 @@ add_executable( ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp ${MGL_ROOT}/MobileGL/MG_Backend/Init.cpp ${MGL_ROOT}/MobileGL/MG_Util/Debug/Log.cpp + ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp ) target_include_directories(BufferTest PRIVATE diff --git a/MobileGL/MG_Test/Program/CMakeLists.txt b/MobileGL/MG_Test/Program/CMakeLists.txt index 95c616f4..38b3d47c 100644 --- a/MobileGL/MG_Test/Program/CMakeLists.txt +++ b/MobileGL/MG_Test/Program/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable( ${MGL_ROOT}/MobileGL/MG_Util/Converters/GLToGlslang/GLShaderLangConverter.cpp ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp + ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp ) target_include_directories(ProgramUtilTest PRIVATE @@ -35,6 +36,8 @@ add_executable( ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp + ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp + ${MGL_ROOT}/MobileGL/MG_State/GLState/Core.cpp ${MGL_ROOT}/MobileGL/MG_State/GLState/BufferState/BufferState.cpp ${MGL_ROOT}/MobileGL/MG_State/GLState/BufferState/BufferObject.cpp diff --git a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp index b6249bd1..2a278761 100644 --- a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp @@ -7,6 +7,8 @@ #include #include #include + +#include "MG_Util/ShaderTranspiler/glslang/UniformTraverser.h" using namespace MobileGL; class ProgramUtilTest : public ::testing::Test { @@ -165,6 +167,54 @@ TEST_F(ProgramUtilTest, CompileFragmentShaderWithDiscard) { } } +const char* vs_location = R"(#version 460 + +in vec4 Position; + +layout(location = 1) uniform mat4 ProjMat; +layout(location = 20) uniform vec2 InSize; +layout(location = 0) uniform vec2 OutSize; + +out vec2 texCoord; +out vec2 oneTexel; + +void main(){ + vec4 outPos = ProjMat * vec4(Position.xy, 0.0, 1.0); + gl_Position = vec4(outPos.xy, 0.2, 1.0); + + oneTexel = 1.0 / InSize; + + texCoord = Position.xy / OutSize; +})"; + +TEST_F(ProgramUtilTest, CompileVertexShaderWithLocation) { + using namespace MG_Util::ShaderTranspiler; + ShaderAttrib attrib { + .shaderType = GL_VERTEX_SHADER, + .sourceStr = vs_location, + .flags = ShaderCompileBits::CompileForOpenGL + }; + auto res = ShaderCompiler::CompileShader(attrib); + if (!res) { + ASSERT_NE(res.error().errc, 0); + FAIL() << "errc: " << res.error().errc << "\nlog: " << res.error().log; + } + UnorderedMap uniforms; + + auto pShader = res.value(); + auto root = pShader->getIntermediate()->getTreeRoot(); + UniformTraverser traverser; + root->traverse(&traverser); + auto& symbols = traverser.GetCollectedSymbols(); + for (const auto& symbol : symbols) { + uniforms[symbol->getName().c_str()] = symbol->getQualifier().layoutLocation; + } + + EXPECT_EQ(uniforms["ProjMat"], 1); + EXPECT_EQ(uniforms["InSize"], 20); + EXPECT_EQ(uniforms["OutSize"], 0); +} + TEST_F(ProgramUtilTest, CompileAndLinkProgram) { using namespace MG_Util::ShaderTranspiler; ShaderAttrib vs_attrib { diff --git a/MobileGL/MG_Test/VertexArray/CMakeLists.txt b/MobileGL/MG_Test/VertexArray/CMakeLists.txt index 3ab508c3..638c45fd 100644 --- a/MobileGL/MG_Test/VertexArray/CMakeLists.txt +++ b/MobileGL/MG_Test/VertexArray/CMakeLists.txt @@ -36,6 +36,7 @@ add_executable( ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp ${MGL_ROOT}/MobileGL/MG_Backend/Init.cpp ${MGL_ROOT}/MobileGL/MG_Util/Debug/Log.cpp + ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp ) target_include_directories(VertexArrayTest PRIVATE diff --git a/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp b/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp new file mode 100644 index 00000000..d9804eab --- /dev/null +++ b/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp @@ -0,0 +1,39 @@ +// +// Created by Swung 0x48 on 2025/7/20. +// + +#include "UniformTraverser.h" + +namespace MobileGL { +namespace MG_Util { +namespace ShaderTranspiler { + void UniformTraverser::visitSymbol(glslang::TIntermSymbol *symbol) { + auto parent = getParentNode(); + if (!parent) + return; + auto parentAgg = parent->getAsAggregate(); + if (!parentAgg || parentAgg->getOp() != glslang::EOpLinkerObjects) + return; + + const auto &type = symbol->getType(); + if (symbol->getQualifier().isUniform()) { + m_collectedSymbols.emplace_back(symbol); + // auto& name = symbol->getName(); + // auto qualifier = symbol->getQualifier(); + // + // printf("layout(location = %d) uniform %s\n", qualifier.layoutLocation, name.c_str()); + // auto &uniform = uniforms.emplace_back(); + // uniform.name = name; + // uniform.storageQualifier = qualifier.storage; + // uniform.layoutLocation = qualifier.layoutLocation; + // uniform.layoutBinding = qualifier.layoutBinding; + // uniform.layoutPacking = qualifier.layoutPacking; + } else if (type.getBasicType() == glslang::EbtSampler) { + // auto &uniform = samplers.emplace_back(); + // uniform.name = symbol->getName(); + // uniform.sampler = type.getSampler(); + } + } +} +} +} diff --git a/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.h b/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.h new file mode 100644 index 00000000..bcc5a84a --- /dev/null +++ b/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.h @@ -0,0 +1,24 @@ +// +// Created by Swung 0x48 on 2025/7/20. +// + +#ifndef MOBILEGL_UNIFORMTRAVERSER_H +#define MOBILEGL_UNIFORMTRAVERSER_H + +#include "Includes.h" + +namespace MobileGL { +namespace MG_Util { +namespace ShaderTranspiler { + class UniformTraverser : public glslang::TIntermTraverser { + public: + void visitSymbol(glslang::TIntermSymbol *symbol) override; + Vector& GetCollectedSymbols() { return m_collectedSymbols; } + private: + Vector m_collectedSymbols; + }; +} +} +} + +#endif //MOBILEGL_UNIFORMTRAVERSER_H From d1942bc57d84faf3df63dbdb031a118bcd1d82eb Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 13 Aug 2025 16:31:15 +0800 Subject: [PATCH 3/5] [Feat] (MG_Test/Program): test uniform without location --- MobileGL/MG_Test/Program/ProgramUtilTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp index 2a278761..58f650fb 100644 --- a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp @@ -173,7 +173,7 @@ in vec4 Position; layout(location = 1) uniform mat4 ProjMat; layout(location = 20) uniform vec2 InSize; -layout(location = 0) uniform vec2 OutSize; +uniform vec2 OutSize; out vec2 texCoord; out vec2 oneTexel; @@ -212,7 +212,7 @@ TEST_F(ProgramUtilTest, CompileVertexShaderWithLocation) { EXPECT_EQ(uniforms["ProjMat"], 1); EXPECT_EQ(uniforms["InSize"], 20); - EXPECT_EQ(uniforms["OutSize"], 0); + EXPECT_EQ(uniforms["OutSize"], 4095); } TEST_F(ProgramUtilTest, CompileAndLinkProgram) { From bfb62872c9c98765257266da01637df113c5efdc Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 13 Aug 2025 16:41:46 +0800 Subject: [PATCH 4/5] [Fix] (MG_State/Program): use vector to save uniforms instead --- .../GLState/ProgramState/ShaderObject.cpp | 7 ++++++- .../MG_State/GLState/ProgramState/ShaderObject.h | 2 +- MobileGL/MG_Test/Program/ProgramUtilTest.cpp | 15 ++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp index d90f40e9..646ec7c7 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp @@ -67,7 +67,12 @@ namespace MobileGL { root->traverse(&traverser); auto& symbols = traverser.GetCollectedSymbols(); for (const auto& symbol : symbols) { - m_uniforms[symbol->getName().c_str()] = symbol->getQualifier().layoutLocation; + auto layoutLoc = symbol->getQualifier().layoutLocation; + if (layoutLoc >= m_uniforms.size()) { + m_uniforms.reserve(std::bit_ceil(layoutLoc)); + m_uniforms.resize(layoutLoc + 1); + } + m_uniforms[layoutLoc] = symbol->getName().c_str(); } return true; diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h index 60a0285d..70a598b5 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h @@ -73,7 +73,7 @@ namespace MobileGL { const ShaderStage m_stage; String m_source; SharedPtr m_shader; - UnorderedMap m_uniforms; + Vector m_uniforms; String m_infoLog; Bool m_deleteStatus = false; diff --git a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp index 58f650fb..6701e5f7 100644 --- a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp @@ -199,7 +199,7 @@ TEST_F(ProgramUtilTest, CompileVertexShaderWithLocation) { ASSERT_NE(res.error().errc, 0); FAIL() << "errc: " << res.error().errc << "\nlog: " << res.error().log; } - UnorderedMap uniforms; + Vector uniforms; auto pShader = res.value(); auto root = pShader->getIntermediate()->getTreeRoot(); @@ -207,12 +207,17 @@ TEST_F(ProgramUtilTest, CompileVertexShaderWithLocation) { root->traverse(&traverser); auto& symbols = traverser.GetCollectedSymbols(); for (const auto& symbol : symbols) { - uniforms[symbol->getName().c_str()] = symbol->getQualifier().layoutLocation; + auto layoutLoc = symbol->getQualifier().layoutLocation; + if (layoutLoc >= uniforms.size()) { + uniforms.reserve(std::bit_ceil(layoutLoc)); + uniforms.resize(layoutLoc + 1); + } + uniforms[layoutLoc] = symbol->getName().c_str(); } - EXPECT_EQ(uniforms["ProjMat"], 1); - EXPECT_EQ(uniforms["InSize"], 20); - EXPECT_EQ(uniforms["OutSize"], 4095); + EXPECT_EQ(uniforms[1], "ProjMat"); + EXPECT_EQ(uniforms[20], "InSize"); + EXPECT_EQ(uniforms[4095], "OutSize"); } TEST_F(ProgramUtilTest, CompileAndLinkProgram) { From 09d1e035ed4e77d3862c5c46ffb14ad78d5db136 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 13 Aug 2025 17:05:21 +0800 Subject: [PATCH 5/5] Revert "[Fix] (MG_State/Program): use vector to save uniforms instead" This reverts commit bfb62872c9c98765257266da01637df113c5efdc. --- .../GLState/ProgramState/ShaderObject.cpp | 7 +------ .../MG_State/GLState/ProgramState/ShaderObject.h | 2 +- MobileGL/MG_Test/Program/ProgramUtilTest.cpp | 15 +++++---------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp index 646ec7c7..d90f40e9 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp @@ -67,12 +67,7 @@ namespace MobileGL { root->traverse(&traverser); auto& symbols = traverser.GetCollectedSymbols(); for (const auto& symbol : symbols) { - auto layoutLoc = symbol->getQualifier().layoutLocation; - if (layoutLoc >= m_uniforms.size()) { - m_uniforms.reserve(std::bit_ceil(layoutLoc)); - m_uniforms.resize(layoutLoc + 1); - } - m_uniforms[layoutLoc] = symbol->getName().c_str(); + m_uniforms[symbol->getName().c_str()] = symbol->getQualifier().layoutLocation; } return true; diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h index 70a598b5..60a0285d 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h @@ -73,7 +73,7 @@ namespace MobileGL { const ShaderStage m_stage; String m_source; SharedPtr m_shader; - Vector m_uniforms; + UnorderedMap m_uniforms; String m_infoLog; Bool m_deleteStatus = false; diff --git a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp index 6701e5f7..58f650fb 100644 --- a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp @@ -199,7 +199,7 @@ TEST_F(ProgramUtilTest, CompileVertexShaderWithLocation) { ASSERT_NE(res.error().errc, 0); FAIL() << "errc: " << res.error().errc << "\nlog: " << res.error().log; } - Vector uniforms; + UnorderedMap uniforms; auto pShader = res.value(); auto root = pShader->getIntermediate()->getTreeRoot(); @@ -207,17 +207,12 @@ TEST_F(ProgramUtilTest, CompileVertexShaderWithLocation) { root->traverse(&traverser); auto& symbols = traverser.GetCollectedSymbols(); for (const auto& symbol : symbols) { - auto layoutLoc = symbol->getQualifier().layoutLocation; - if (layoutLoc >= uniforms.size()) { - uniforms.reserve(std::bit_ceil(layoutLoc)); - uniforms.resize(layoutLoc + 1); - } - uniforms[layoutLoc] = symbol->getName().c_str(); + uniforms[symbol->getName().c_str()] = symbol->getQualifier().layoutLocation; } - EXPECT_EQ(uniforms[1], "ProjMat"); - EXPECT_EQ(uniforms[20], "InSize"); - EXPECT_EQ(uniforms[4095], "OutSize"); + EXPECT_EQ(uniforms["ProjMat"], 1); + EXPECT_EQ(uniforms["InSize"], 20); + EXPECT_EQ(uniforms["OutSize"], 4095); } TEST_F(ProgramUtilTest, CompileAndLinkProgram) {