[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 "GL_Program.h"
#include "MG_State/GLState/Core.h" #include "MG_State/GLState/Core.h"
#include "MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.h"
namespace MobileGL { namespace MobileGL {
namespace MG_Impl::GLImpl { namespace MG_Impl::GLImpl {
@@ -60,6 +61,9 @@ namespace MobileGL {
auto sz = std::min(bufSize - 1, srcLength); auto sz = std::min(bufSize - 1, srcLength);
if (length) if (length)
*length = sz; *length = sz;
if (bufSize == 0) return;
memcpy(dst, src, sz); memcpy(dst, src, sz);
dst[sz] = '\0'; dst[sz] = '\0';
} }
@@ -144,7 +148,30 @@ namespace MobileGL {
void GetActiveUniform_State(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, void GetActiveUniform_State(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size,
GLenum* type, GLchar* name) { 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) { 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()); CopyStr(bufSize, length, source, src.c_str(), src.length());
} }
GLint GetUniformLocation_State(GLuint program, const GLchar* name) { GLint GetUniformLocation_State(GLuint program, const GLchar* name) {
auto programObject = TryToGetProgramObject(program); auto programObject = TryToGetProgramObject(program);
if (!programObject) if (!programObject)
@@ -283,7 +308,6 @@ namespace MobileGL {
if (!programObject) if (!programObject)
return; return;
MG_State::pGLContext->UseProgram(program); MG_State::pGLContext->UseProgram(program);
} }
void Uniform1f_State(GLint location, GLfloat v0) { void Uniform1f_State(GLint location, GLfloat v0) {
@@ -1,6 +1,8 @@
#include "ProgramObject.h" #include "ProgramObject.h"
#include <MG_Util/ShaderTranspiler/ShaderCompiler.h> #include <MG_Util/ShaderTranspiler/ShaderCompiler.h>
#include "MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.h"
namespace MobileGL { namespace MobileGL {
namespace MG_State { namespace MG_State {
namespace GLState { namespace GLState {
@@ -75,7 +77,9 @@ namespace MobileGL {
for (const auto& shader : m_shaders) { for (const auto& shader : m_shaders) {
for (const auto& [name, loc] : shader->GetUniformLocations()) { for (const auto& [name, loc] : shader->GetUniformLocations()) {
// collect all the names to map // 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 // set a flag for those who have an explicit location
if (loc != 4095) { 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() { void ProgramObject::PostLink() {
@@ -135,14 +145,20 @@ namespace MobileGL {
assert(false); assert(false);
return; return;
} }
auto& metadata = session.GetMetadata(); m_metadata = session.GetMetadata();
auto& uniformOffsets = metadata.plainUniformOffsetsInUBO; auto& uniformOffsets = m_metadata.plainUniformOffsetsInUBO;
for (const auto& [name, offset] : uniformOffsets) { for (const auto& [name, offset] : uniformOffsets) {
assert(m_uniforms.find(name) != m_uniforms.end()); assert(m_uniforms.find(name) != m_uniforms.end());
assert(m_uniforms[name] < m_uniformOffsets.size()); assert(m_uniforms[name] < m_uniformOffsets.size());
m_uniformOffsets[m_uniforms[name]] = offset; 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 GLState
} // namespace MG_State } // namespace MG_State
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <Includes.h> #include <Includes.h>
#include "ShaderObject.h" #include "ShaderObject.h"
#include "MG_Util/ShaderTranspiler/SpvcSession.h"
namespace MobileGL { namespace MobileGL {
namespace MG_State { namespace MG_State {
@@ -15,10 +16,19 @@ namespace MobileGL {
void MarkAsDeleted(); void MarkAsDeleted();
Vector<SharedPtr<ShaderObject>>& GetAttachedShaders(); Vector<SharedPtr<ShaderObject>>& GetAttachedShaders();
const String& GetInfoLog() const { return m_infoLog; } const String& GetInfoLog() const { return m_infoLog; }
Int GetUniformMaxLength() const { return m_uniformNameMaxLength; }
Uint GetUniformCount() { return m_uniformOffsets.size(); }
Int GetUniformLocation(const String& name) { Int GetUniformLocation(const String& name) {
const auto it = m_uniforms.find(name); const auto it = m_uniforms.find(name);
return (it == m_uniforms.end()) ? -1 : it->second; 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: private:
void PreLink(); void PreLink();
void PostLink(); void PostLink();
@@ -29,12 +39,19 @@ namespace MobileGL {
Vector<Vector<Uint>> m_programBinary; Vector<Vector<Uint>> m_programBinary;
// Uniforms // Uniforms
MG_Util::ShaderTranspiler::SpvcMetadata m_metadata;
UnorderedMap<String, Uint> m_uniforms; UnorderedMap<String, Uint> m_uniforms;
// 0 or 1 for if the location is explicitly specified at PreLink stage, // 0 or 1 for if the location is explicitly specified at PreLink stage,
// offsets into global ubo for PostLink // offsets into global ubo for PostLink
Vector<Uint> m_uniformOffsets; Vector<Uint> m_uniformOffsets;
Vector<String> m_uniformNames;
Vector<GLenum> m_uniformTypes;
Vector<Uint8> m_uboScratch; Vector<Uint8> m_uboScratch;
Int m_uniformNameMaxLength = 0;
String m_infoLog; String m_infoLog;
Bool m_deleteStatus = false; Bool m_deleteStatus = false;
Bool m_linkStatus = true; Bool m_linkStatus = true;
+1
View File
@@ -37,6 +37,7 @@ add_executable(
${MGL_ROOT}/MobileGL/MG_Backend/Init.cpp ${MGL_ROOT}/MobileGL/MG_Backend/Init.cpp
${MGL_ROOT}/MobileGL/MG_Util/Debug/Log.cpp ${MGL_ROOT}/MobileGL/MG_Util/Debug/Log.cpp
${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp
${MGL_ROOT}/MobileGL/MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.cpp
) )
target_include_directories(BufferTest PRIVATE 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/SpvcSession.cpp
${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.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/Core.cpp
${MGL_ROOT}/MobileGL/MG_State/GLState/BufferState/BufferState.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_Backend/Init.cpp
${MGL_ROOT}/MobileGL/MG_Util/Debug/Log.cpp ${MGL_ROOT}/MobileGL/MG_Util/Debug/Log.cpp
${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp ${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/glslang/UniformTraverser.cpp
${MGL_ROOT}/MobileGL/MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.cpp
) )
target_include_directories(VertexArrayTest PRIVATE target_include_directories(VertexArrayTest PRIVATE