From 5b3d5c998a9db47e32c3166ddf13c5e45ced1eb4 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Mon, 27 Oct 2025 13:17:42 +0800 Subject: [PATCH] [Feat] (MG_State/ProgramObject, MG_State/GL_Program): implement sampler unit in program state --- .../MG_Impl/GLImpl/Program/GL_Program.cpp | 15 +++++++++++---- .../GLState/ProgramState/ProgramObject.cpp | 1 + .../GLState/ProgramState/ProgramObject.h | 19 +++++++++++++++++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index 182e060a..3cc2bb54 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -455,10 +455,17 @@ namespace MobileGL { template void Uniform_State(MG_State::GLState::ProgramObject& programObject, GLuint location, T* value) { - auto size = programObject.GetUniformSizesInBytes(location); - auto offset = programObject.GetUniformOffset(location); - assert(size >= VecCount * sizeof(T)); - memcpy((char*)programObject.MapUBO() + offset, value, VecCount * sizeof(T)); + if (!programObject.IsUniformOpaqueAtLocation(location)) { + auto size = programObject.GetUniformSizesInBytes(location); + auto offset = programObject.GetUniformOffset(location); + assert(size >= VecCount * sizeof(T)); + memcpy((char*)programObject.MapUBO() + offset, value, VecCount * sizeof(T)); + } else { + auto* ttype = programObject.GetUniformTType(location); + if (ttype->isTexture() || ttype->isImage()) { + programObject.SetUniformSamplerOrImageUnitIndex(location, *value); + } + } } template diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp index 3b7b0f58..f51eb45a 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp @@ -92,6 +92,7 @@ namespace MobileGL { // 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, 0); Vector unallocatedUniformIndex; diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h index bc0c4bde..8dc9118f 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h @@ -29,14 +29,19 @@ namespace MobileGL { return -1; return (Int)it->second; } + GLenum GetUniformType(Uint location) const { auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]); return uniform.glDefineType; } - Bool IsUniformOpaqueAtLocation(Uint location) const { + const glslang::TType* GetUniformTType(Uint location) const { auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]); - return uniform.getType()->isOpaque(); + return uniform.getType(); + } + + Bool IsUniformOpaqueAtLocation(Uint location) const { + return GetUniformTType(location)->isOpaque(); } const String& GetUniformName(Uint location) const { @@ -56,6 +61,14 @@ namespace MobileGL { const String& GetAttribName(Uint index) const { return m_attribs[index]; } void* MapUBO() { return m_uboScratch.data(); } + void SetUniformSamplerOrImageUnitIndex(Uint location, Int unit) { + m_uniformSamplerOrImageUnitIndex[location] = unit; + } + + Int SetUniformSamplerOrImageUnitIndex(Uint location) const { + return m_uniformSamplerOrImageUnitIndex[location]; + } + Bool GetDeleteStatus() const { return m_deleteStatus; } Bool GetLinkStatus() const { return m_linkStatus; } Bool GetValidateStatus() const { return m_validateStatus; } @@ -91,6 +104,8 @@ namespace MobileGL { // Ordered by location, // aka. m_uniformIndexInTProgram[loc] == "uniform index of TProgram at location `loc`" Vector m_uniformIndexInTProgram; + // ditto. Will be set at glUniform1i + Vector m_uniformSamplerOrImageUnitIndex; // Need to be reflected after linking of SPIR-V binary Vector m_uniformOffsets;