[Feat] (MG_State/Program): GetActiveUniform

This commit is contained in:
2025-08-14 13:50:34 +08:00
parent eb926848be
commit 238d0ffade
6 changed files with 68 additions and 8 deletions
+28 -4
View File
@@ -1,6 +1,7 @@
#include "GL_Program.h"
#include "MG_State/GLState/Core.h"
#include "MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.h"
namespace MobileGL {
namespace MG_Impl::GLImpl {
@@ -60,6 +61,9 @@ namespace MobileGL {
auto sz = std::min(bufSize - 1, srcLength);
if (length)
*length = sz;
if (bufSize == 0) return;
memcpy(dst, src, sz);
dst[sz] = '\0';
}
@@ -144,7 +148,30 @@ namespace MobileGL {
void GetActiveUniform_State(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size,
GLenum* type, GLchar* name) {
THROW_UNIMPL_EXCEPTION;
if (bufSize < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`bufSize` is less than 0."));
return;
}
auto programObject = TryToGetProgramObject(program);
if (!programObject)
return;
auto uniformCount = programObject->GetUniformCount();
if (index >= uniformCount) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`index` is greater than or equal to the number of active uniform variables in `program`."));
return;
}
if (type != nullptr)
*type = programObject->GetUniformType(index);
if (bufSize == 0) return;
auto& uniformName = programObject->GetUniformName(index);
CopyStr(bufSize, length, name, uniformName.c_str(), uniformName.length());
}
void GetAttachedShaders_State(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
@@ -213,8 +240,6 @@ namespace MobileGL {
CopyStr(bufSize, length, source, src.c_str(), src.length());
}
GLint GetUniformLocation_State(GLuint program, const GLchar* name) {
auto programObject = TryToGetProgramObject(program);
if (!programObject)
@@ -283,7 +308,6 @@ namespace MobileGL {
if (!programObject)
return;
MG_State::pGLContext->UseProgram(program);
}
void Uniform1f_State(GLint location, GLfloat v0) {
@@ -1,6 +1,8 @@
#include "ProgramObject.h"
#include <MG_Util/ShaderTranspiler/ShaderCompiler.h>
#include "MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
@@ -75,7 +77,9 @@ namespace MobileGL {
for (const auto& shader : m_shaders) {
for (const auto& [name, loc] : shader->GetUniformLocations()) {
// collect all the names to map
m_uniforms[name] = loc;
if (loc != 4095 || m_uniforms.find(name) == m_uniforms.end()) {
m_uniforms[name] = loc;
}
// set a flag for those who have an explicit location
if (loc != 4095) {
@@ -121,6 +125,12 @@ namespace MobileGL {
}
}
}
m_uniformNames.resize(m_uniformOffsets.size());
for (auto& [name, loc] : m_uniforms) {
m_uniformNames[loc] = name;
m_uniformNameMaxLength = std::max(m_uniformNameMaxLength, (Int)name.length());
}
}
void ProgramObject::PostLink() {
@@ -135,14 +145,20 @@ namespace MobileGL {
assert(false);
return;
}
auto& metadata = session.GetMetadata();
auto& uniformOffsets = metadata.plainUniformOffsetsInUBO;
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(metadata.uboSize);
m_uniformTypes.resize(uniformOffsets.size());
for (const auto& [name, type] : m_metadata.plainUniformMemberTypes) {
m_uniformTypes[m_uniforms[name]] = MG_Util::ConvertSpvcTypeToGLEnum(type);
}
m_uboScratch.resize(m_metadata.uboSize, 0);
}
} // namespace GLState
} // namespace MG_State
@@ -1,6 +1,7 @@
#pragma once
#include <Includes.h>
#include "ShaderObject.h"
#include "MG_Util/ShaderTranspiler/SpvcSession.h"
namespace MobileGL {
namespace MG_State {
@@ -15,10 +16,19 @@ namespace MobileGL {
void MarkAsDeleted();
Vector<SharedPtr<ShaderObject>>& GetAttachedShaders();
const String& GetInfoLog() const { return m_infoLog; }
Int GetUniformMaxLength() const { return m_uniformNameMaxLength; }
Uint GetUniformCount() { return m_uniformOffsets.size(); }
Int GetUniformLocation(const String& name) {
const auto it = m_uniforms.find(name);
return (it == m_uniforms.end()) ? -1 : it->second;
}
GLenum GetUniformType(Uint index) const {
return m_uniformTypes[index];
}
const String& GetUniformName(Uint index) const {
return m_uniformNames[index];
}
private:
void PreLink();
void PostLink();
@@ -29,12 +39,19 @@ namespace MobileGL {
Vector<Vector<Uint>> m_programBinary;
// Uniforms
MG_Util::ShaderTranspiler::SpvcMetadata m_metadata;
UnorderedMap<String, Uint> m_uniforms;
// 0 or 1 for if the location is explicitly specified at PreLink stage,
// offsets into global ubo for PostLink
Vector<Uint> m_uniformOffsets;
Vector<String> m_uniformNames;
Vector<GLenum> m_uniformTypes;
Vector<Uint8> m_uboScratch;
Int m_uniformNameMaxLength = 0;
String m_infoLog;
Bool m_deleteStatus = false;
Bool m_linkStatus = true;
+1
View File
@@ -37,6 +37,7 @@ add_executable(
${MGL_ROOT}/MobileGL/MG_Backend/Init.cpp
${MGL_ROOT}/MobileGL/MG_Util/Debug/Log.cpp
${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp
${MGL_ROOT}/MobileGL/MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.cpp
)
target_include_directories(BufferTest PRIVATE
+1
View File
@@ -37,6 +37,7 @@ add_executable(
${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/SpvcSession.cpp
${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp
${MGL_ROOT}/MobileGL/MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.cpp
${MGL_ROOT}/MobileGL/MG_State/GLState/Core.cpp
${MGL_ROOT}/MobileGL/MG_State/GLState/BufferState/BufferState.cpp
@@ -37,6 +37,7 @@ add_executable(
${MGL_ROOT}/MobileGL/MG_Backend/Init.cpp
${MGL_ROOT}/MobileGL/MG_Util/Debug/Log.cpp
${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp
${MGL_ROOT}/MobileGL/MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.cpp
)
target_include_directories(VertexArrayTest PRIVATE