mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-09 04:38:30 +09:00
[Fix] (MG_State/ProgramState): Separate detach/remove shader in ProgramObject. Add more log.
This commit is contained in:
@@ -565,7 +565,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MG_External::GLES::glGetProgramiv(m_backendProgramId, GL_INFO_LOG_LENGTH, &logLength);
|
||||
Vector<GLchar> log(logLength);
|
||||
MG_External::GLES::glGetProgramInfoLog(m_backendProgramId, logLength, nullptr, log.data());
|
||||
MGLOG_E("Program linking failed for %u: %s", m_backendProgramId, log.data());
|
||||
MGLOG_E("Program %u linking failed for %u: %s", stateProgramObject->GetExternalIndex(),
|
||||
m_backendProgramId, log.data());
|
||||
} else {
|
||||
MGLOG_D("Program linked successfully. ID: %u", m_backendProgramId);
|
||||
}
|
||||
|
||||
@@ -8,79 +8,143 @@ namespace MobileGL {
|
||||
namespace MG_State {
|
||||
namespace GLState {
|
||||
bool ProgramObject::ShaderIsAttached(SharedPtr<ShaderObject> shader) {
|
||||
MGLOG_D("ProgramObject %u: ShaderIsAttached check for shader %p", m_externalIndex, shader.get());
|
||||
auto it = std::find_if(m_shaders.begin(), m_shaders.end(),
|
||||
[shader](const SharedPtr<ShaderObject>& s) { return s.get() == shader.get(); });
|
||||
return it != m_shaders.end();
|
||||
bool attached = it != m_shaders.end();
|
||||
MGLOG_D("ProgramObject %u: ShaderIsAttached -> %s", m_externalIndex, attached ? "true" : "false");
|
||||
return attached;
|
||||
}
|
||||
|
||||
bool ProgramObject::AttachShader(SharedPtr<ShaderObject> shader) {
|
||||
if (ShaderIsAttached(shader)) return false;
|
||||
MGLOG_D("ProgramObject %u: AttachShader called for shader %p", m_externalIndex, shader.get());
|
||||
if (ShaderIsAttached(shader)) {
|
||||
MGLOG_D("ProgramObject %u: AttachShader - shader already attached, skipping", m_externalIndex);
|
||||
return false;
|
||||
}
|
||||
m_shaders.emplace_back(shader);
|
||||
MGLOG_D("ProgramObject %u: AttachShader - attached successfully, total shaders now %zu",
|
||||
m_externalIndex, m_shaders.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
SizeT ProgramObject::DetachShader(SharedPtr<ShaderObject> shader) {
|
||||
MGLOG_D("DetachShader called for shader %p from ProgramObject %u", shader.get(), m_externalIndex);
|
||||
if (!ShaderIsAttached(shader)) {
|
||||
MGLOG_D("Shader %p is not attached to ProgramObject %u, cannot detach.", shader.get(),
|
||||
m_externalIndex);
|
||||
return 0;
|
||||
}
|
||||
m_detachedShaders.push_back(shader);
|
||||
MGLOG_D("Shader %p marked for detachment from ProgramObject %u", shader.get(), m_externalIndex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
SizeT ProgramObject::RemoveShader(SharedPtr<ShaderObject> shader) {
|
||||
MGLOG_D("ProgramObject %u: RemoveShader called for shader %p", m_externalIndex, shader.get());
|
||||
auto count = std::erase_if(
|
||||
m_shaders, [shader](const SharedPtr<ShaderObject>& s) { return s.get() == shader.get(); });
|
||||
|
||||
MGLOG_D("ProgramObject %u: RemoveShader - removed %zu shader(s), remaining %zu", m_externalIndex, count,
|
||||
m_shaders.size());
|
||||
return count;
|
||||
}
|
||||
|
||||
void ProgramObject::Link() {
|
||||
MGLOG_D("ProgramObject %u: Link start, shaders to link: %zu", m_externalIndex, m_shaders.size());
|
||||
// Remove detached shaders first
|
||||
for (const auto& detachedShader : m_detachedShaders) {
|
||||
RemoveShader(detachedShader);
|
||||
}
|
||||
m_detachedShaders.clear();
|
||||
|
||||
Vector<GLenum> shaderTypes(m_shaders.size());
|
||||
Vector<SharedPtr<glslang::TShader>> shaders(m_shaders.size());
|
||||
MGLOG_D("%s: shaders to link: %d\n", __func__, m_shaders.size());
|
||||
|
||||
for (SizeT i = 0; i < m_shaders.size(); i++) {
|
||||
shaderTypes[i] = MG_Util::ConvertShaderStageToGLEnum(m_shaders[i]->GetShaderStage());
|
||||
MGLOG_D("ProgramObject %u: Preparing shader[%zu] stage %s at %p", m_externalIndex, i,
|
||||
MG_Util::ConvertGLEnumToString(shaderTypes[i]).c_str(), m_shaders[i].get());
|
||||
|
||||
if (!m_shaders[i]->GetCompileStatus()) {
|
||||
m_infoLog = std::format("Linking a {} with compilation error, linking will now terminate. Shader error log:\n{}\nShader src:\n{}",
|
||||
MG_Util::ConvertGLEnumToString(shaderTypes[i]).c_str(),
|
||||
m_shaders[i]->GetInfoLog().c_str(), m_shaders[i]->GetShaderSource().c_str());
|
||||
m_infoLog =
|
||||
std::format("Linking a {} with compilation error, linking will now terminate. Shader error "
|
||||
"log:\n{}\nShader src:\n{}",
|
||||
MG_Util::ConvertGLEnumToString(shaderTypes[i]).c_str(),
|
||||
m_shaders[i]->GetInfoLog().c_str(), m_shaders[i]->GetShaderSource().c_str());
|
||||
m_linkStatus = false;
|
||||
MGLOG_W("%s", m_infoLog.c_str());
|
||||
MGLOG_E("ProgramObject %u: Link failed - shader[%zu] compile status false. InfoLog:\n%s",
|
||||
m_externalIndex, i, m_infoLog.c_str());
|
||||
return;
|
||||
}
|
||||
shaders[i] = m_shaders[i]->GetCompiledShader();
|
||||
MGLOG_D("%s: \n%s",
|
||||
MG_Util::ConvertGLEnumToString(shaderTypes[i]).c_str(), m_shaders[i]->GetShaderSource().c_str());
|
||||
MGLOG_D("ProgramObject %u: shader[%zu] compiled shader ptr %p, src len %zu", m_externalIndex, i,
|
||||
shaders[i].get(), m_shaders[i]->GetShaderSource().length());
|
||||
MGLOG_D("ProgramObject %u: shader[%zu] source:\n%s", m_externalIndex, i,
|
||||
m_shaders[i]->GetShaderSource().c_str());
|
||||
}
|
||||
|
||||
MG_Util::ShaderTranspiler::ProgramAttrib attrib{
|
||||
.shaders = Move(shaders),
|
||||
};
|
||||
|
||||
MGLOG_D("ProgramObject %u: Calling ShaderCompiler::LinkProgram", m_externalIndex);
|
||||
auto result = MG_Util::ShaderTranspiler::ShaderCompiler::LinkProgram(attrib);
|
||||
if (result) {
|
||||
m_linkStatus = true;
|
||||
m_program = result.value();
|
||||
MGLOG_D("ProgramObject %u: LinkProgram succeeded, TProgram ptr %p", m_externalIndex,
|
||||
m_program.get());
|
||||
} else {
|
||||
m_linkStatus = false;
|
||||
m_infoLog = result.error().log;
|
||||
MGLOG_W("%s", m_infoLog.c_str());
|
||||
MGLOG_E("ProgramObject %u: LinkProgram failed. InfoLog:\n%s", m_externalIndex, m_infoLog.c_str());
|
||||
}
|
||||
|
||||
MGLOG_D("ProgramObject %u: Starting reflection", m_externalIndex);
|
||||
DoReflection();
|
||||
MGLOG_D("ProgramObject %u: Reflection done (linkStatus=%d)", m_externalIndex, (int)m_linkStatus);
|
||||
|
||||
MGLOG_D("ProgramObject %u: Starting binary generation", m_externalIndex);
|
||||
GenerateBinary();
|
||||
MGLOG_D("ProgramObject %u: Binary generation finished (generatedSpirv size=%zu)", m_externalIndex,
|
||||
m_generatedSpirv.size());
|
||||
}
|
||||
|
||||
void ProgramObject::MarkAsDeleted() {
|
||||
MGLOG_D("ProgramObject %u: MarkAsDeleted called (was %s)", m_externalIndex,
|
||||
m_deleteStatus ? "deleted" : "not deleted");
|
||||
m_deleteStatus = true;
|
||||
MGLOG_D("ProgramObject %u: MarkAsDeleted - now marked deleted", m_externalIndex);
|
||||
}
|
||||
|
||||
Vector<SharedPtr<ShaderObject>>& ProgramObject::GetAttachedShaders() {
|
||||
MGLOG_D("ProgramObject %u: GetAttachedShaders called, returning %zu shaders", m_externalIndex,
|
||||
m_shaders.size());
|
||||
return m_shaders;
|
||||
}
|
||||
|
||||
void ProgramObject::DoReflection() {
|
||||
if (!m_program) {
|
||||
MGLOG_E("ProgramObject %u: DoReflection called but m_program is null", m_externalIndex);
|
||||
m_linkStatus = false;
|
||||
m_infoLog = "DoReflection failed: no program.";
|
||||
return;
|
||||
}
|
||||
|
||||
MGLOG_D("ProgramObject %u: DoReflection - building reflection", m_externalIndex);
|
||||
if (!m_program->buildReflection()) {
|
||||
m_linkStatus = false;
|
||||
m_infoLog = "Build reflection failed.";
|
||||
MGLOG_E("ProgramObject %u: DoReflection - buildReflection() returned false", m_externalIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------ Uniforms (GL Plain) ----------------
|
||||
// Allocate uniform locations
|
||||
m_activeUniformCount = m_program->getNumUniformVariables();
|
||||
MGLOG_D("ProgramObject %u: Reflection - active uniform count = %d", m_externalIndex,
|
||||
m_activeUniformCount);
|
||||
for (int i = 0; i < m_activeUniformCount; i++) {
|
||||
auto& uniform = m_program->getUniform(i);
|
||||
auto location = uniform.layoutLocation();
|
||||
@@ -89,17 +153,23 @@ namespace MobileGL {
|
||||
}
|
||||
m_uniformNameMaxLength = std::max(m_uniformNameMaxLength, (Int)uniform.name.length());
|
||||
m_uniformLocations[uniform.name] = location;
|
||||
MGLOG_D("ProgramObject %u: Reflection - uniform[%d] name='%s' layoutLocation=%d", m_externalIndex,
|
||||
i, uniform.name.c_str(), location);
|
||||
}
|
||||
|
||||
MGLOG_D("ProgramObject %u: Reflection - computed m_maxUniformLocation=%u m_uniformNameMaxLength=%d",
|
||||
m_externalIndex, m_maxUniformLocation, m_uniformNameMaxLength);
|
||||
|
||||
if (m_maxUniformLocation + 1 < m_activeUniformCount) {
|
||||
MGLOG_D("ProgramObject %u: Reflection - maxUniformLocation+1 (%u) < activeUniformCount (%d), "
|
||||
"adjusting",
|
||||
m_externalIndex, m_maxUniformLocation + 1, m_activeUniformCount);
|
||||
// This means we have fewer than enough gaps to fit
|
||||
// unallocated uniforms
|
||||
m_maxUniformLocation = m_activeUniformCount;
|
||||
}
|
||||
|
||||
// i-th elements refers to uniform at layout(location = i, ...)
|
||||
// Be aware, there could be gaps in between these vectors
|
||||
// Locations can be not sequential
|
||||
m_uniformIndexInTProgram.resize(m_maxUniformLocation + 1, 4095);
|
||||
m_uniformSamplerOrImageUnitIndex.resize(m_maxUniformLocation + 1, -1);
|
||||
|
||||
@@ -111,9 +181,13 @@ namespace MobileGL {
|
||||
auto location = uniform.layoutLocation();
|
||||
if (m_uniformLocations[uniform.name] == 4095) {
|
||||
unallocatedUniformIndex.emplace_back(i);
|
||||
MGLOG_D("ProgramObject %u: Reflection - uniform '%s' is unallocated, will assign later",
|
||||
m_externalIndex, uniform.name.c_str());
|
||||
continue; // will allocate unallocated uniforms later
|
||||
}
|
||||
m_uniformIndexInTProgram[location] = i;
|
||||
MGLOG_D("ProgramObject %u: Reflection - assigned uniform '%s' to location %d (indexInTProgram=%d)",
|
||||
m_externalIndex, uniform.name.c_str(), location, i);
|
||||
}
|
||||
|
||||
SizeT locNeedle = 0;
|
||||
@@ -124,16 +198,24 @@ namespace MobileGL {
|
||||
// Found a vacant location at locNeedle
|
||||
m_uniformIndexInTProgram[locNeedle] = index;
|
||||
m_uniformLocations[uniform.name] = locNeedle;
|
||||
MGLOG_D("ProgramObject %u: Reflection - assigned unallocated uniform '%s' to location %zu "
|
||||
"(index %d)",
|
||||
m_externalIndex, uniform.name.c_str(), locNeedle, index);
|
||||
locNeedle++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int inCount = m_program->getNumPipeInputs();
|
||||
MGLOG_D("ProgramObject %u: Reflection - pipe input count (attributes) = %d", m_externalIndex, inCount);
|
||||
|
||||
int maxLoc = -1;
|
||||
for (int i = 0; i < inCount; ++i) {
|
||||
int loc = m_program->getPipeInput(i).layoutLocation();
|
||||
if (loc >= 0) maxLoc = std::max(maxLoc, loc);
|
||||
MGLOG_D("ProgramObject %u: Reflection - pipe input[%d] name='%s' layoutLocation=%d glType=%u",
|
||||
m_externalIndex, i, m_program->getPipeInput(i).name.c_str(), loc,
|
||||
m_program->getPipeInput(i).glDefineType);
|
||||
}
|
||||
|
||||
if (maxLoc < 0) {
|
||||
@@ -141,11 +223,13 @@ namespace MobileGL {
|
||||
}
|
||||
|
||||
GLint maxAttribs = 16; // TODO: get from backend
|
||||
MGLOG_D("ProgramObject %u: Reflection - computed maxLoc=%d, using maxAttribs=%d", m_externalIndex,
|
||||
maxLoc, maxAttribs);
|
||||
|
||||
if (maxLoc >= maxAttribs) {
|
||||
MGLOG_W("ProgramObject::DoReflection - required attrib location %d >= GL_MAX_VERTEX_ATTRIBS (%d). "
|
||||
"Clamping.",
|
||||
maxLoc, maxAttribs);
|
||||
MGLOG_W("ProgramObject %u: ProgramObject::DoReflection - required attrib location %d >= "
|
||||
"GL_MAX_VERTEX_ATTRIBS (%d). Clamping.",
|
||||
m_externalIndex, maxLoc, maxAttribs);
|
||||
maxLoc = maxAttribs - 1;
|
||||
}
|
||||
|
||||
@@ -160,9 +244,12 @@ namespace MobileGL {
|
||||
if (location >= 0 && location < (int)m_attribs.size()) {
|
||||
m_attribs[location] = inVar.name;
|
||||
m_attribTypes[location] = inVar.glDefineType;
|
||||
MGLOG_D("ProgramObject %u: Reflection - placed attrib '%s' at explicit location %d",
|
||||
m_externalIndex, inVar.name.c_str(), location);
|
||||
} else if (location >= (int)m_attribs.size()) {
|
||||
MGLOG_W("ProgramObject::DoReflection - attrib location %d >= attribs.size() (%zu). Ignoring.",
|
||||
location, m_attribs.size());
|
||||
MGLOG_W("ProgramObject %u: ProgramObject::DoReflection - attrib location %d >= attribs.size() "
|
||||
"(%zu). Ignoring.",
|
||||
m_externalIndex, location, m_attribs.size());
|
||||
continue;
|
||||
} else {
|
||||
bool placed = false;
|
||||
@@ -171,6 +258,8 @@ namespace MobileGL {
|
||||
m_attribs[idx] = inVar.name;
|
||||
m_attribTypes[idx] = inVar.glDefineType;
|
||||
placed = true;
|
||||
MGLOG_D("ProgramObject %u: Reflection - placed attrib '%s' into free slot %zu",
|
||||
m_externalIndex, inVar.name.c_str(), idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -178,44 +267,62 @@ namespace MobileGL {
|
||||
m_attribs.push_back(inVar.name);
|
||||
m_attribTypes.push_back(inVar.glDefineType);
|
||||
placed = true;
|
||||
MGLOG_D("ProgramObject %u: Reflection - pushed attrib '%s' to new slot %zu",
|
||||
m_externalIndex, inVar.name.c_str(), m_attribs.size() - 1);
|
||||
}
|
||||
if (!placed) {
|
||||
MGLOG_W("ProgramObject::DoReflection - cannot place attrib '%s' (no free slot and at max "
|
||||
"capacity). Ignoring.",
|
||||
inVar.name.c_str());
|
||||
MGLOG_W("ProgramObject %u: ProgramObject::DoReflection - cannot place attrib '%s' (no free "
|
||||
"slot and at max capacity). Ignoring.",
|
||||
m_externalIndex, inVar.name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement glBindAttribLocation semantics (explicit locations set by user)
|
||||
for (auto& [name, location] : m_explicitAttribLocations) {
|
||||
MGLOG_D("ProgramObject %u: Reflection - explicit attrib location request: name='%s' location=%d",
|
||||
m_externalIndex, name.c_str(), location);
|
||||
if (location < 0) continue;
|
||||
if (location >= (int)m_attribs.size()) {
|
||||
if (location >= maxAttribs) {
|
||||
MGLOG_W("SetExplicitAttribLocation: requested location %d >= GL_MAX_VERTEX_ATTRIBS (%d). "
|
||||
"Ignored for attribute '%s'.",
|
||||
location, maxAttribs, name.c_str());
|
||||
MGLOG_W("ProgramObject %u: SetExplicitAttribLocation: requested location %d >= "
|
||||
"GL_MAX_VERTEX_ATTRIBS (%d). Ignored for attribute '%s'.",
|
||||
m_externalIndex, location, maxAttribs, name.c_str());
|
||||
continue;
|
||||
}
|
||||
m_attribs.resize(location + 1);
|
||||
m_attribTypes.resize(location + 1);
|
||||
MGLOG_D("ProgramObject %u: Reflection - resized attrib arrays to %zu to accommodate explicit "
|
||||
"location %d",
|
||||
m_externalIndex, m_attribs.size(), location);
|
||||
}
|
||||
|
||||
if (m_attribs[location] != name) {
|
||||
auto it = std::find(m_attribs.begin(), m_attribs.end(), name);
|
||||
if (it == m_attribs.end()) continue;
|
||||
if (it == m_attribs.end()) {
|
||||
MGLOG_D("ProgramObject %u: Reflection - explicit attrib '%s' not found in current list, "
|
||||
"skipping swap",
|
||||
m_externalIndex, name.c_str());
|
||||
continue;
|
||||
}
|
||||
auto idx = std::distance(m_attribs.begin(), it);
|
||||
std::swap(m_attribs[location], m_attribs[idx]);
|
||||
std::swap(m_attribTypes[location], m_attribTypes[idx]);
|
||||
MGLOG_D("ProgramObject %u: Reflection - swapped attrib '%s' from idx %zu to explicit "
|
||||
"location %d",
|
||||
m_externalIndex, name.c_str(), idx, location);
|
||||
}
|
||||
|
||||
for (SizeT idx = 0; idx < m_attribs.size(); ++idx) {
|
||||
m_attribLocation[m_attribs[idx]] = idx;
|
||||
MGLOG_D("ProgramObject %u: Reflection - attribLocation['%s'] = %zu", m_externalIndex,
|
||||
m_attribs[idx].c_str(), idx);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- UBO ----------
|
||||
int uboCount = m_program->getNumUniformBlocks();
|
||||
MGLOG_D("ProgramObject %u: Reflection - uniform block count (UBO) = %d", m_externalIndex, uboCount);
|
||||
m_uniformBlockBinding.resize(uboCount, -1);
|
||||
for (int i = 0; i < uboCount; i++) {
|
||||
auto& ubo = m_program->getUniformBlock(i);
|
||||
@@ -224,6 +331,8 @@ namespace MobileGL {
|
||||
// if there's binding defined in shader as layout(binding = ...),
|
||||
// retrieve it here
|
||||
m_uniformBlockBinding[i] = ubo.getBinding();
|
||||
MGLOG_D("ProgramObject %u: Reflection - UBO[%d] name='%s' size=%u binding=%d", m_externalIndex, i,
|
||||
ubo.name.c_str(), ubo.size, ubo.getBinding());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,6 +343,7 @@ namespace MobileGL {
|
||||
* here without the burden of error reporting.
|
||||
*/
|
||||
using namespace MG_Util::ShaderTranspiler;
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - start", m_externalIndex);
|
||||
Vector<SharedPtr<glslang::TShader>> shaders(m_shaders.size());
|
||||
Vector<GLenum> shaderTypes(m_shaders.size());
|
||||
for (SizeT i = 0; i < m_shaders.size(); i++) {
|
||||
@@ -241,32 +351,58 @@ namespace MobileGL {
|
||||
shaderTypes[i] = shaderType;
|
||||
ShaderAttrib attrib{
|
||||
.shaderType = shaderType, .sourceStr = m_shaders[i]->GetShaderSource(), .flags = 0};
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - compiling shader[%zu] type %u", m_externalIndex, i,
|
||||
shaderType);
|
||||
auto res = ShaderCompiler::CompileShader(attrib);
|
||||
assert(res);
|
||||
if (!res) {
|
||||
MGLOG_E("ProgramObject %u: GenerateBinary - CompileShader failed for shader[%zu], aborting "
|
||||
"binary generation",
|
||||
m_externalIndex, i);
|
||||
assert(res); // keep original assert but log first
|
||||
}
|
||||
shaders[i] = res.value();
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - compiled shader[%zu] -> TShader ptr %p",
|
||||
m_externalIndex, i, shaders[i].get());
|
||||
}
|
||||
|
||||
ProgramAttrib attrib{
|
||||
.shaders = Move(shaders),
|
||||
};
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - linking program for binary", m_externalIndex);
|
||||
auto programResult = ShaderCompiler::LinkProgram(attrib);
|
||||
if (!programResult) {
|
||||
MGLOG_E("ProgramObject %u: GenerateBinary - LinkProgram failed during binary generation",
|
||||
m_externalIndex);
|
||||
}
|
||||
assert(programResult);
|
||||
auto program = programResult.value();
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - got linked program object", m_externalIndex);
|
||||
|
||||
ProgramBinaryAttrib binaryAttrib{
|
||||
.shaderTypes = shaderTypes,
|
||||
.program = *program,
|
||||
};
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - requesting SPIR-V binary from program", m_externalIndex);
|
||||
auto binaryResult = ShaderCompiler::GetSpirvBinaryFromProgram(binaryAttrib);
|
||||
if (!binaryResult) {
|
||||
MGLOG_E("ProgramObject %u: GenerateBinary - GetSpirvBinaryFromProgram failed", m_externalIndex);
|
||||
}
|
||||
assert(binaryResult);
|
||||
m_generatedSpirv = Move(binaryResult.value());
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - generated %zu SPIR-V modules", m_externalIndex,
|
||||
m_generatedSpirv.size());
|
||||
|
||||
for (SizeT i = 0; i < m_generatedSpirv.size(); i++) {
|
||||
auto& spv = m_generatedSpirv[i];
|
||||
auto shaderType = shaderTypes[i];
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - parsing SPIR-V meta data for module %zu "
|
||||
"(shaderType=%u, wordCount=%zu)",
|
||||
m_externalIndex, i, shaderType, spv.size());
|
||||
SpvcSession session(spv);
|
||||
auto result = session.ParseMetaData();
|
||||
if (result < 0) {
|
||||
MGLOG_E("ProgramObject %u: GenerateBinary - SpvcSession::ParseMetaData failed for module %zu",
|
||||
m_externalIndex, i);
|
||||
continue;
|
||||
}
|
||||
// auto srcResult = ShaderCompiler::DecompileShader(session);
|
||||
@@ -276,28 +412,55 @@ namespace MobileGL {
|
||||
|
||||
auto& meta = session.GetMetadata();
|
||||
auto size = meta.uboSize;
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - SPIR-V meta: uboSize=%zu plainUniformCount=%zu "
|
||||
"plainUniformOffsets=%zu",
|
||||
m_externalIndex, meta.uboSize, meta.plainUniformMemberSizesInBytes.size(),
|
||||
meta.plainUniformOffsetsInUBO.size());
|
||||
m_uboScratch.resize(size);
|
||||
m_uniformOffsets.resize(m_maxUniformLocation + 1);
|
||||
for (const auto& [name, offset] : meta.plainUniformOffsetsInUBO) {
|
||||
if (m_uniformLocations.find(name) != m_uniformLocations.end())
|
||||
if (m_uniformLocations.find(name) != m_uniformLocations.end()) {
|
||||
m_uniformOffsets[m_uniformLocations[name]] = offset;
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' offset=%u assigned to location %u",
|
||||
m_externalIndex, name.c_str(), offset, m_uniformLocations[name]);
|
||||
} else {
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' offset=%u but not found in "
|
||||
"m_uniformLocations",
|
||||
m_externalIndex, name.c_str(), offset);
|
||||
}
|
||||
}
|
||||
m_uniformSizesInBytes.resize(m_maxUniformLocation + 1);
|
||||
for (const auto& [name, size] : meta.plainUniformMemberSizesInBytes) {
|
||||
if (m_uniformLocations.find(name) != m_uniformLocations.end())
|
||||
if (m_uniformLocations.find(name) != m_uniformLocations.end()) {
|
||||
m_uniformSizesInBytes[m_uniformLocations[name]] = size;
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' size=%u assigned to location %u",
|
||||
m_externalIndex, name.c_str(), size, m_uniformLocations[name]);
|
||||
} else {
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' size=%u but not found in "
|
||||
"m_uniformLocations",
|
||||
m_externalIndex, name.c_str(), size);
|
||||
}
|
||||
}
|
||||
// assert(m_uniformOffsets.size() == GetUniformCount());
|
||||
// assert(m_uniformSizesInBytes.size() == GetUniformCount());
|
||||
// Only parse first module that contains uniform metadata
|
||||
MGLOG_D("ProgramObject %u: GenerateBinary - finished parsing module %zu; breaking after first "
|
||||
"valid metadata",
|
||||
m_externalIndex, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramObject::WaitUntilGenerationCompleted() {}
|
||||
void ProgramObject::WaitUntilGenerationCompleted() {
|
||||
MGLOG_D("ProgramObject %u: WaitUntilGenerationCompleted called (no-op)", m_externalIndex);
|
||||
// currently no-op, but keep log for debugging
|
||||
}
|
||||
|
||||
void ProgramObject::SetExplicitAttribLocation(Uint index, const char* name) {
|
||||
MGLOG_D("ProgramObject %u: SetExplicitAttribLocation called name='%s' index=%u", m_externalIndex, name,
|
||||
index);
|
||||
m_explicitAttribLocations[name] = index;
|
||||
MGLOG_D("ProgramObject %u: SetExplicitAttribLocation - stored explicit location for '%s' -> %u",
|
||||
m_externalIndex, name, index);
|
||||
}
|
||||
} // namespace GLState
|
||||
} // namespace MG_State
|
||||
} // namespace MobileGL
|
||||
} // namespace MobileGL
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace MobileGL {
|
||||
bool ShaderIsAttached(SharedPtr<ShaderObject> shader);
|
||||
bool AttachShader(SharedPtr<ShaderObject> shader);
|
||||
SizeT DetachShader(SharedPtr<ShaderObject> shader);
|
||||
SizeT RemoveShader(SharedPtr<ShaderObject> shader);
|
||||
void Link();
|
||||
void MarkAsDeleted();
|
||||
|
||||
@@ -77,35 +78,27 @@ namespace MobileGL {
|
||||
Int GetActiveUniformBlocksMaxNameLength() const { return m_uniformBlockNameMaxLength; }
|
||||
Uint GetUniformBlockIndex(const char* name) const {
|
||||
auto it = m_uniformBlockIndexByName.find(name);
|
||||
if (it != m_uniformBlockIndexByName.end())
|
||||
return it->second;
|
||||
if (it != m_uniformBlockIndexByName.end()) return it->second;
|
||||
return 0xFFFFFFFFu; // GL_INVALID_INDEX
|
||||
}
|
||||
Bool IsActiveUniformBlock(Uint index) const {
|
||||
if (index >= GetActiveUniformBlocksCount())
|
||||
return false;
|
||||
if (index >= GetActiveUniformBlocksCount()) return false;
|
||||
return true;
|
||||
}
|
||||
Uint GetUBOSizeAt(Uint index) const {
|
||||
if (!IsActiveUniformBlock(index))
|
||||
return 0;
|
||||
if (!IsActiveUniformBlock(index)) return 0;
|
||||
return m_program->getUniformBlock(index).size;
|
||||
}
|
||||
|
||||
|
||||
const String& GetUniformBlockName(Uint index) const {
|
||||
auto& ubo = m_program->getUniformBlock(index);
|
||||
return ubo.name;
|
||||
}
|
||||
|
||||
// Set by glUniformBlockBinding
|
||||
void SetUniformBlockBinding(Uint index, Uint binding) {
|
||||
m_uniformBlockBinding[index] = binding;
|
||||
}
|
||||
void SetUniformBlockBinding(Uint index, Uint binding) { m_uniformBlockBinding[index] = binding; }
|
||||
|
||||
Uint GetUniformBlockBinding(Uint index) const {
|
||||
return m_uniformBlockBinding[index];
|
||||
}
|
||||
Uint GetUniformBlockBinding(Uint index) const { return m_uniformBlockBinding[index]; }
|
||||
|
||||
Vector<Vector<unsigned>>& GetGeneratedSpirv() { return m_generatedSpirv; }
|
||||
|
||||
@@ -120,6 +113,7 @@ namespace MobileGL {
|
||||
|
||||
const Uint m_externalIndex = 0;
|
||||
Vector<SharedPtr<ShaderObject>> m_shaders;
|
||||
Vector<SharedPtr<ShaderObject>> m_detachedShaders; // Store detached shaders and remove on next link
|
||||
|
||||
SharedPtr<glslang::TProgram> m_program;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user