diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp index 99a06c5b..c1a6eaed 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp @@ -26,7 +26,7 @@ namespace MobileGL { } void ProgramObject::Link() { - PreLink(); + // PreLink(); Vector shaderTypes(m_shaders.size()); Vector> shaders(m_shaders.size()); @@ -43,7 +43,7 @@ namespace MobileGL { auto result = MG_Util::ShaderTranspiler::ShaderCompiler::LinkProgram(attrib); if (result) { m_linkStatus = true; - m_programBinary = Move(result.value()); + m_program = result.value(); } else { m_linkStatus = false; m_infoLog = result.error().log; @@ -53,7 +53,7 @@ namespace MobileGL { THROW_EXCEPTION(e); } - PostLink(); + // PostLink(); } void ProgramObject::MarkAsDeleted() { @@ -127,35 +127,35 @@ namespace MobileGL { } void ProgramObject::PostLink() { - if (m_programBinary.empty()) { - assert(false); - return; - } - MG_Util::ShaderTranspiler::SpvcSession session(m_programBinary[0]); - const char* src = nullptr; // we don't care the source atm - auto result = session.Compile(&src); - if (result != SPVC_SUCCESS) { - assert(false); - return; - } - m_metadata = session.GetMetadata(); - auto& uniformOffsets = m_metadata.plainUniformOffsetsInUBO; - for (const auto& [name, offset] : uniformOffsets) { - assert(m_uniforms.find(name) != m_uniforms.end()); - assert(m_uniforms[name] < m_uniformOffsets.size()); - m_uniformOffsets[m_uniforms[name]] = offset; - } - m_uboScratch.resize(m_metadata.uboSize, 0); - - auto& types = m_metadata.plainUniformMemberTypes; - - assert(types.size() == m_uniformOffsets.size()); - m_uniformTypes.resize(m_uniformOffsets.size()); - for (const auto& [name, type] : types) { - auto gltype = MG_Util::ConvertSpvcTypeToGLEnum(type); - auto location = m_uniforms[name]; - m_uniformTypes[location] = gltype; - } + // if (m_programBinary.empty()) { + // assert(false); + // return; + // } + // MG_Util::ShaderTranspiler::SpvcSession session(m_programBinary[0]); + // const char* src = nullptr; // we don't care the source atm + // auto result = session.Compile(&src); + // if (result != SPVC_SUCCESS) { + // assert(false); + // return; + // } + // m_metadata = session.GetMetadata(); + // auto& uniformOffsets = m_metadata.plainUniformOffsetsInUBO; + // for (const auto& [name, offset] : uniformOffsets) { + // assert(m_uniforms.find(name) != m_uniforms.end()); + // assert(m_uniforms[name] < m_uniformOffsets.size()); + // m_uniformOffsets[m_uniforms[name]] = offset; + // } + // m_uboScratch.resize(m_metadata.uboSize, 0); + // + // auto& types = m_metadata.plainUniformMemberTypes; + // + // assert(types.size() == m_uniformOffsets.size()); + // m_uniformTypes.resize(m_uniformOffsets.size()); + // for (const auto& [name, type] : types) { + // auto gltype = MG_Util::ConvertSpvcTypeToGLEnum(type); + // auto location = m_uniforms[name]; + // m_uniformTypes[location] = gltype; + // } } } // namespace GLState } // namespace MG_State diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h index 6309da71..1133460f 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h @@ -35,8 +35,8 @@ namespace MobileGL { const Uint m_id = 0; Vector> m_shaders; - // basically this contains SPIR-V in binary format - Vector> m_programBinary; + + SharedPtr m_program; // Uniforms MG_Util::ShaderTranspiler::SpvcMetadata m_metadata; diff --git a/MobileGL/MG_Test/Program/ProgramTest.cpp b/MobileGL/MG_Test/Program/ProgramTest.cpp index 3504e45a..fba40d91 100644 --- a/MobileGL/MG_Test/Program/ProgramTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramTest.cpp @@ -113,6 +113,9 @@ TEST_F(ProgramTest, CompileAndLink) { LinkProgram(program); printf("Program linked.\n"); + // FIXME: fix these later, refactoring uniform location reflection stuff + FAIL() << "GetUniformLocation not implemented yet!"; + EXPECT_EQ(GetUniformLocation(program, "ProjMat"), 0); EXPECT_EQ(GetUniformLocation(program, "Gray"), 1); EXPECT_EQ(GetUniformLocation(program, "Saturation"), 6); diff --git a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp index 58f650fb..da2d5506 100644 --- a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp @@ -143,8 +143,15 @@ TEST_F(ProgramUtilTest, CompileFragmentShaderWithDiscard) { FAIL() << "errc: " << program_res.error().errc << "\nlog: " << program_res.error().log; } + auto program = program_res.value(); - auto spirvs = program_res.value(); + ProgramBinaryAttrib binaryAttrib { + .shaderTypes = { GL_FRAGMENT_SHADER }, + .program = *program, + }; + auto bin_res = ShaderCompiler::GetSpirvBinaryFromProgram(binaryAttrib); + + auto spirvs = bin_res.value(); Vector sessions(spirvs.size()); for (SizeT i = 0; i < spirvs.size(); ++i) { @@ -282,7 +289,13 @@ TEST_F(ProgramUtilTest, DecompProgram) { FAIL() << "errc: " << program_res.error().errc << "\nlog: " << program_res.error().log; } - auto spirvs = program_res.value(); + ProgramBinaryAttrib binaryAttrib { + .shaderTypes = { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER }, + .program = *program_res.value(), + }; + auto bin_res = ShaderCompiler::GetSpirvBinaryFromProgram(binaryAttrib); + + auto spirvs = bin_res.value(); Vector sessions(spirvs.size()); for (SizeT i = 0; i < spirvs.size(); ++i) { diff --git a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp index f98faf69..f9971ea3 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp @@ -159,22 +159,22 @@ namespace MobileGL { return res; } - Result>> ShaderCompiler::LinkProgram(const ProgramAttrib& attrib) { - glslang::TProgram program; + Result> ShaderCompiler::LinkProgram(const ProgramAttrib& attrib) { + SharedPtr program = MakeShared(); for (auto& s : attrib.shaders) { - program.addShader(s.get()); + program->addShader(s.get()); } - if (!program.link(EShMsgDefault)) { + if (!program->link(EShMsgDefault)) { ResultInfo r; - r.log = "Error: [glslang] Cannot link the program:\n" + std::string(program.getInfoLog()); + r.log = "Error: [glslang] Cannot link the program:\n" + std::string(program->getInfoLog()); r.errc = -3; return std::unexpected(r); } UniquePtr resolver; for (unsigned stage = 0; stage < EShLangCount; stage++) { - auto* pResolver = program.getGlslIoResolver((EShLanguage)stage); + auto* pResolver = program->getGlslIoResolver((EShLanguage)stage); if (pResolver) { resolver = UniquePtr(pResolver); break; @@ -182,20 +182,24 @@ namespace MobileGL { } auto ioMapper = UniquePtr(glslang::GetGlslIoMapper()); - if (!program.mapIO(resolver.get(), ioMapper.get())) { + if (!program->mapIO(resolver.get(), ioMapper.get())) { ResultInfo r; - r.log = "Error: [glslang] Cannot mapIO:\n" + std::string(program.getInfoLog()); + r.log = "Error: [glslang] Cannot mapIO:\n" + std::string(program->getInfoLog()); r.errc = -4; return std::unexpected(r); } + return program; + } + + Result>> ShaderCompiler::GetSpirvBinaryFromProgram(const ProgramBinaryAttrib &attrib) { glslang::SpvOptions spvOptions; spvOptions.disableOptimizer = false; Vector> allSpirv; for (auto type : attrib.shaderTypes) { Vector spirv; - GlslangToSpv(*program.getIntermediate(ConvertGLEnumToEShLanguage(type)), spirv, &spvOptions); + GlslangToSpv(*attrib.program.getIntermediate(ConvertGLEnumToEShLanguage(type)), spirv, &spvOptions); allSpirv.push_back(spirv); } diff --git a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.h b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.h index 0fadb5de..6c6ef566 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.h +++ b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.h @@ -8,7 +8,8 @@ namespace MobileGL { class ShaderCompiler { public: static Result> CompileShader(const ShaderAttrib& attrib); - static Result>> LinkProgram(const ProgramAttrib& attrib); + static Result> LinkProgram(const ProgramAttrib& attrib); + static Result>> GetSpirvBinaryFromProgram(const ProgramBinaryAttrib& attrib); static Result DecompileShader(SpvcSession& session); }; } // namespace ShaderTranspiler diff --git a/MobileGL/MG_Util/ShaderTranspiler/Types.h b/MobileGL/MG_Util/ShaderTranspiler/Types.h index dc0fc2c8..c4c90ef1 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/Types.h +++ b/MobileGL/MG_Util/ShaderTranspiler/Types.h @@ -24,6 +24,11 @@ namespace MobileGL { Vector> shaders; }; + struct ProgramBinaryAttrib { + Vector shaderTypes; + const glslang::TProgram& program; + }; + struct ResultInfo { Int errc = 0; String log;