From 19071c021797e82c960f8f58cbd915f785a456ca Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 11 Aug 2025 16:02:42 +0800 Subject: [PATCH 1/5] [Fix] (MG_State/Program): typo in ProgramState::CreateProgram --- MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp index b90c276d..a90a9457 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp @@ -7,7 +7,7 @@ namespace MobileGL { Uint programId = 0; m_programIndexGenerator.Generate(1, &programId); EnsureIndexAvail(programId, m_programObjects); - auto programObject = MakeShared(programId); + auto programObject = MakeShared(); if (programObject == nullptr) return 0; m_programObjects[programId] = programObject; From 75177113081f8e8824d8499da27008ed71d15fa2 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 11 Aug 2025 16:15:32 +0800 Subject: [PATCH 2/5] [Chore] (workflow): test 4 parallel jobs --- .github/workflows/benchmark.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 39683de1..319f794c 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -44,7 +44,7 @@ jobs: - name: Build working-directory: ${{env.BENCH_ROOT}}/build-bench - run: cmake --build . --parallel 1 + run: cmake --build . --parallel 4 - name: Benchmark working-directory: ${{env.BENCH_ROOT}}/build-bench diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b279802b..353a3954 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -44,7 +44,7 @@ jobs: - name: Build working-directory: ${{env.TEST_ROOT}}/build-test - run: cmake --build . --parallel 1 + run: cmake --build . --parallel 4 - name: Test working-directory: ${{env.TEST_ROOT}}/build-test From 21a46ee15141d2c84f6a392afbd6db61c3c29582 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 11 Aug 2025 16:47:18 +0800 Subject: [PATCH 3/5] [Feat] (MG_State/Program): glShaderSource, glUseProgram --- .../MG_Impl/GLImpl/Program/GL_Program.cpp | 29 +++++++++++++++++-- MobileGL/MG_State/GLState/Core.cpp | 4 +++ MobileGL/MG_State/GLState/Core.h | 1 + .../GLState/ProgramState/ProgramState.cpp | 8 +++++ .../GLState/ProgramState/ProgramState.h | 4 +++ .../GLState/ProgramState/ShaderObject.cpp | 4 +++ .../GLState/ProgramState/ShaderObject.h | 1 + 7 files changed, 49 insertions(+), 2 deletions(-) diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index d65a1db5..0e7cea03 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -203,11 +203,36 @@ namespace MobileGL { } void ShaderSource_State(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) { - THROW_UNIMPL_EXCEPTION; + if (count < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", __func__, + "`count` is less than 0.")); + } + + auto programObject = TryToGetShaderObject(shader); + if (!programObject) + return; + + std::string src; + for (GLsizei i = 0; i < count; i++) { + src += + (length[i] <= 0) ? string[i] : std::string(string[i], length[i]); + } + programObject->SetShaderSource(Move(src)); } void UseProgram_State(GLuint program) { - THROW_UNIMPL_EXCEPTION; + if (program == 0) { + MG_State::pGLContext->UseProgram(0); + return; + } + + auto programObject = TryToGetProgramObject(program); + if (!programObject) + return; + MG_State::pGLContext->UseProgram(program); + } void Uniform1f_State(GLint location, GLfloat v0) { diff --git a/MobileGL/MG_State/GLState/Core.cpp b/MobileGL/MG_State/GLState/Core.cpp index 92c190ea..3f28f6f4 100644 --- a/MobileGL/MG_State/GLState/Core.cpp +++ b/MobileGL/MG_State/GLState/Core.cpp @@ -187,6 +187,10 @@ namespace MobileGL { SharedPtr GLContext::GetShaderObject(const Uint index) { return m_programState.GetShaderObject(index); } + + void GLContext::UseProgram(Uint program) { + return m_programState.UseProgram(program); + } } // namespace GLState GLState::GLContext* pGLContext; diff --git a/MobileGL/MG_State/GLState/Core.h b/MobileGL/MG_State/GLState/Core.h index b3bb10c6..e57d0785 100644 --- a/MobileGL/MG_State/GLState/Core.h +++ b/MobileGL/MG_State/GLState/Core.h @@ -63,6 +63,7 @@ namespace MobileGL { Bool ValidateShaderName(Uint index) const; SharedPtr GetProgramObject(Uint index); SharedPtr GetShaderObject(Uint index); + void UseProgram(Uint program); private: // Error ErrorState m_errorState; diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp index a90a9457..6f290128 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp @@ -33,6 +33,14 @@ namespace MobileGL { return CheckIndexAvail(program, m_programObjects) && m_programObjects[program] != nullptr; } + void ProgramState::UseProgram(Uint program) { + if (program == 0) + m_currentProgram.reset(); + + if (!CheckIndexAvail(program, m_programObjects)) return; + m_currentProgram = m_programObjects[program]; + } + Uint ProgramState::CreateShader(ShaderStage stage) { Uint shaderId = 0; m_shaderIndexGenerator.Generate(1, &shaderId); diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramState.h b/MobileGL/MG_State/GLState/ProgramState/ProgramState.h index 85a653a0..ff981cb1 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramState.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramState.h @@ -15,6 +15,8 @@ namespace MobileGL { void MarkProgramObjectForDeletion(Uint program); Bool ValidateProgramObject(Uint program) const; + void UseProgram(Uint program); + Uint CreateShader(ShaderStage stage); SharedPtr GetShaderObject(Uint shader); void MarkShaderObjectForDeletion(Uint shader); @@ -38,6 +40,8 @@ namespace MobileGL { IndexGenerator m_shaderIndexGenerator; Vector> m_shaderObjects; + + SharedPtr m_currentProgram; }; } // namespace GLState } // namespace MG_State diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp index fbbd93de..3345f025 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp @@ -8,6 +8,10 @@ namespace MobileGL { m_source = source; } + void ShaderObject::SetShaderSource(std::string &&source) { + m_source = Move(source); + } + void ShaderObject::Compile() { using namespace MG_Util::ShaderTranspiler; ShaderAttrib attrib{ diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h index c743a629..3d14af78 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h @@ -58,6 +58,7 @@ namespace MobileGL { public: ShaderObject(const ShaderStage stage) : m_stage(stage) {} void SetShaderSource(const std::string& source); + void SetShaderSource(std::string&& source); void Compile(); void MarkAsDeleted(); From 408b62a4952267c56512df4a3fda3fca62553cdd Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 11 Aug 2025 23:07:15 +0800 Subject: [PATCH 4/5] [Feat] (MG_State/Program): GetAttachedShaders --- MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp | 18 +++++++++++++++++- .../GLState/ProgramState/ProgramObject.cpp | 4 ++++ .../GLState/ProgramState/ProgramObject.h | 3 +++ .../GLState/ProgramState/ProgramState.cpp | 4 ++-- .../GLState/ProgramState/ShaderObject.h | 4 +++- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index 0e7cea03..508fbfa0 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -140,7 +140,23 @@ namespace MobileGL { } void GetAttachedShaders_State(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) { - THROW_UNIMPL_EXCEPTION; + if (maxCount < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", __func__, + "`maxCount` is less than 0.")); + return; + } + auto programObject = TryToGetProgramObject(program); + if (!programObject) + return; + const auto& s = programObject->GetAttachedShaders(); + GLsizei c = std::min((GLsizei)s.size(), maxCount); + if (count) + *count = c; + for (GLsizei i = 0; i < c; ++i) { + shaders[i] = s[i]->GetId(); + } } GLint GetAttribLocation_State(GLuint program, const GLchar* name) { diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp index a82c57a9..db9bc49a 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp @@ -59,6 +59,10 @@ namespace MobileGL { void ProgramObject::MarkAsDeleted() { m_deleteStatus = true; } + + 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/ProgramObject.h b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h index 1946707d..a4e5b1b5 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h @@ -7,12 +7,15 @@ namespace MobileGL { namespace GLState { class ProgramObject { public: + ProgramObject(const Uint id): m_id(id) {} bool ShaderIsAttached(SharedPtr shader); bool AttachShader(SharedPtr shader); SizeT DetachShader(SharedPtr shader); void Link(); void MarkAsDeleted(); + Vector>& GetAttachedShaders(); private: + const Uint m_id = 0; Vector> m_shaders; // basically this contains SPIR-V in binary format Vector> m_programBinary; diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp index 6f290128..fb7f22eb 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp @@ -7,7 +7,7 @@ namespace MobileGL { Uint programId = 0; m_programIndexGenerator.Generate(1, &programId); EnsureIndexAvail(programId, m_programObjects); - auto programObject = MakeShared(); + auto programObject = MakeShared(programId); if (programObject == nullptr) return 0; m_programObjects[programId] = programObject; @@ -45,7 +45,7 @@ namespace MobileGL { Uint shaderId = 0; m_shaderIndexGenerator.Generate(1, &shaderId); EnsureIndexAvail(shaderId, m_shaderObjects); - auto shaderObject = MakeShared(stage); + auto shaderObject = MakeShared(stage, shaderId); if (shaderObject == nullptr) return 0; m_shaderObjects[shaderId] = shaderObject; diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h index 3d14af78..271c7939 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h @@ -56,16 +56,18 @@ namespace MobileGL { class ShaderObject { public: - ShaderObject(const ShaderStage stage) : m_stage(stage) {} + ShaderObject(const ShaderStage stage, const Uint id) : m_stage(stage), m_id(id) {} void SetShaderSource(const std::string& source); void SetShaderSource(std::string&& source); void Compile(); void MarkAsDeleted(); + Uint GetId() const { return m_id; } ShaderStage GetShaderStage() const { return m_stage; } const std::string& GetShaderSource() const { return m_source; } SharedPtr GetCompiledShader() const { return m_shader; } private: + const Uint m_id = 0; const ShaderStage m_stage; std::string m_source; SharedPtr m_shader; From af32784f379735873ffc87b490fc81122736af06 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 11 Aug 2025 23:19:10 +0800 Subject: [PATCH 5/5] [Feat] (MG_State/Program): GetShaderSource --- .../MG_Impl/GLImpl/Program/GL_Program.cpp | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index 508fbfa0..aaf53306 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -180,7 +180,23 @@ namespace MobileGL { } void GetShaderSource_State(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source) { - THROW_UNIMPL_EXCEPTION; + if (bufSize < 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidValue, + MakeShared("MG_Impl/GLImpl", __func__, + "`bufSize` is less than 0.")); + } + + auto shaderObject = TryToGetShaderObject(shader); + if (!shaderObject) + return; + + auto& src = shaderObject->GetShaderSource(); + auto sz = std::min(bufSize - 1, (GLsizei)src.length()); + if (length) + *length = sz; + memcpy(source, src.c_str(), sz); + source[sz] = '\0'; } GLint GetUniformLocation_State(GLuint program, const GLchar* name) { @@ -226,8 +242,8 @@ namespace MobileGL { "`count` is less than 0.")); } - auto programObject = TryToGetShaderObject(shader); - if (!programObject) + auto shaderObject = TryToGetShaderObject(shader); + if (!shaderObject) return; std::string src; @@ -235,7 +251,7 @@ namespace MobileGL { src += (length[i] <= 0) ? string[i] : std::string(string[i], length[i]); } - programObject->SetShaderSource(Move(src)); + shaderObject->SetShaderSource(Move(src)); } void UseProgram_State(GLuint program) {