[Feat] (MG_State/Program): generate program binary (SPIR-V), reflect generated ubo size/offsets

This commit is contained in:
2025-08-18 11:10:24 +08:00
parent 2036caa4a0
commit cb59bc0431
3 changed files with 57 additions and 2 deletions
@@ -269,7 +269,7 @@ namespace MobileGL {
*params = programObject->GetActiveUniformBlocksCount();
break;
case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: // ditto.
*params = programObject->GetActiveUniformBlocksMaxLength();
*params = programObject->GetActiveUniformBlocksMaxNameLength();
break;
case GL_COMPUTE_WORK_GROUP_SIZE: // GL >= 4.3
@@ -52,6 +52,7 @@ namespace MobileGL {
// PostLink();
DoReflection();
GenerateBinary();
}
void ProgramObject::MarkAsDeleted() {
@@ -119,6 +120,57 @@ namespace MobileGL {
}
}
void ProgramObject::GenerateBinary() {
/* As we passed first stage compilation/linking,
* we'll assume all the operations here should
* pass. We may be able to employ some optimizations
* here without the burden of error reporting.
*/
using namespace MG_Util::ShaderTranspiler;
Vector<SharedPtr<glslang::TShader>> shaders(m_shaders.size());
Vector<GLenum> shaderTypes(m_shaders.size());
for (SizeT i = 0; i < m_shaders.size(); i++) {
auto shaderType = ConvertGLShaderTypeByMGLShaderStage(m_shaders[i]->GetShaderStage());
shaderTypes[i] = shaderType;
ShaderAttrib attrib {
.shaderType = shaderType,
.sourceStr = m_shaders[i]->GetShaderSource(),
.flags = 0
};
auto res = ShaderCompiler::CompileShader(attrib);
assert(res);
shaders[i] = res.value();
}
ProgramAttrib attrib {
.shaders = Move(shaders),
};
auto programResult = ShaderCompiler::LinkProgram(attrib);
assert(programResult);
auto program = programResult.value();
ProgramBinaryAttrib binaryAttrib {
.shaderTypes = shaderTypes,
.program = *program,
};
auto binaryResult = ShaderCompiler::GetSpirvBinaryFromProgram(binaryAttrib);
assert(binaryResult);
m_generatedSpirv = Move(binaryResult.value());
SpvcSession session(m_generatedSpirv[0]);
auto& meta = session.GetMetadata();
auto size = meta.uboSize;
m_uboScratch.resize(size);
m_uniformOffsets.resize(meta.plainUniformOffsetsInUBO.size());
for (const auto& [name, offset] : meta.plainUniformOffsetsInUBO) {
m_uniformOffsets[m_uniformLocations[name]] = offset;
}
auto srcResult = ShaderCompiler::DecompileShader(session);
assert(srcResult);
auto src = srcResult.value();
printf("decompiled src: \n%s", src.c_str());
}
void ProgramObject::SetExplicitAttribLocation(Uint index, const char *name) {
m_explicitAttribLocations[name] = index;
}
@@ -45,9 +45,10 @@ namespace MobileGL {
Int GetActiveAttributesCount() const { return m_program->getNumPipeInputs(); }
Int GetActiveUniformBlocksCount() const { return m_program->getNumUniformBlocks(); }
Int GetActiveAttributesMaxLength() const { return m_attribInNameMaxLength; }
Int GetActiveUniformBlocksMaxLength() const { return m_uniformBlockNameMaxLength; }
Int GetActiveUniformBlocksMaxNameLength() const { return m_uniformBlockNameMaxLength; }
private:
void DoReflection();
void GenerateBinary();
// void PreLink();
// void PostLink();
@@ -56,6 +57,8 @@ namespace MobileGL {
SharedPtr<glslang::TProgram> m_program;
Vector<Vector<unsigned>> m_generatedSpirv;
// Attributes
UnorderedMap<String, Uint> m_explicitAttribLocations;
Vector<String> m_attribs;