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 67a8a98d..f51eb45a 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp @@ -91,11 +91,8 @@ namespace MobileGL { // 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_uniformNames.resize(m_maxUniformLocation + 1); - m_uniformTypes.resize(m_maxUniformLocation + 1, GL_ZERO); - m_uniformIsOpaqueType.resize(m_maxUniformLocation + 1); - m_uniformOffsets.resize(m_maxUniformLocation + 1); - m_uniformArraySizes.resize(m_maxUniformLocation + 1); + m_uniformIndexInTProgram.resize(m_maxUniformLocation + 1, 4095); + m_uniformSamplerOrImageUnitIndex.resize(m_maxUniformLocation + 1, 0); Vector unallocatedUniformIndex; @@ -103,26 +100,21 @@ namespace MobileGL { for (int i = 0; i < m_activeUniformCount; i++) { auto& uniform = m_program->getUniform(i); auto location = uniform.layoutLocation(); - if (location >= m_uniformNames.size()) { + if (m_uniformLocations[uniform.name] == 4095) { unallocatedUniformIndex.emplace_back(i); continue; // will allocate unallocated uniforms later } - m_uniformNames[location] = uniform.name; - m_uniformTypes[location] = uniform.glDefineType; - m_uniformIsOpaqueType[location] = uniform.getType()->isOpaque(); - m_uniformArraySizes[location] = uniform.size; + m_uniformIndexInTProgram[location] = i; } SizeT locNeedle = 0; - for (auto index : unallocatedUniformIndex) { + for (auto index: unallocatedUniformIndex) { auto& uniform = m_program->getUniform(index); for (; locNeedle <= m_maxUniformLocation; locNeedle++) { - if (m_uniformTypes[locNeedle] != GL_ZERO) continue; + if (m_uniformIndexInTProgram[locNeedle] != 4095) + continue; // Found a vacant location at locNeedle - m_uniformNames[locNeedle] = uniform.name; - m_uniformTypes[locNeedle] = uniform.glDefineType; - m_uniformIsOpaqueType[locNeedle] = uniform.getType()->isOpaque(); - m_uniformArraySizes[locNeedle] = uniform.size; + m_uniformIndexInTProgram[locNeedle] = index; m_uniformLocations[uniform.name] = locNeedle; break; } diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h index b4cc5167..3e2bf16d 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h @@ -25,17 +25,32 @@ namespace MobileGL { Uint GetMaxUniformLocation() const { return m_maxUniformLocation; } Int GetUniformLocation(const String& name) { const auto it = m_uniformLocations.find(name); - if (it == m_uniformLocations.end()) return -1; + if (it == m_uniformLocations.end()) + return -1; return (Int)it->second; } - GLenum GetUniformType(Uint index) const { return m_uniformTypes[index]; } - Bool IsUniformOpaqueAtLocation(Uint location) const { return m_uniformIsOpaqueType[location]; } + GLenum GetUniformType(Uint location) const { + auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]); + return uniform.glDefineType; + } - const String& GetUniformName(Uint index) const { return m_uniformNames[index]; } + const glslang::TType* GetUniformTType(Uint location) const { + auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]); + return uniform.getType(); + } + + Bool IsUniformOpaqueAtLocation(Uint location) const { + return GetUniformTType(location)->isOpaque(); + } + + const String& GetUniformName(Uint location) const { + auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]); + return uniform.name; + } Uint GetUniformOffset(Uint location) const { return m_uniformOffsets[location]; } Uint GetUniformSizesInBytes(Uint location) const { - return MG_Util::GetGLTypeSize(m_uniformTypes[location]); + return MG_Util::GetGLTypeSize(GetUniformType(location)); } Int GetAttributeLocation(const String& name) { @@ -47,6 +62,14 @@ namespace MobileGL { void* MapUBO() { return m_uboScratch.data(); } Uint GetUBOSize() const { return static_cast(m_uboScratch.size()); } + 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; } @@ -82,12 +105,10 @@ namespace MobileGL { UnorderedMap m_uniformLocations; // Ordered by location, - // aka. m_uniformNames[loc] == "name at location `loc`" - Vector m_uniformNames; - // ditto. - Vector m_uniformTypes; - Vector m_uniformIsOpaqueType; - Vector m_uniformArraySizes; + // 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;