[Fix]: fix Chocapic V6 Lite

- prune unused SPIR-V interface variables before GLES transpilation

- remap shader varyings through glslang IO resolver bindings

- initialize opaque uniforms from explicit sampler bindings only

- avoid side effects in texture binding assertions

- register Chocapic V6 Lite retrace fixture
This commit is contained in:
2026-06-19 18:42:32 +08:00
parent 7d101182cd
commit 19e4ba386d
11 changed files with 231 additions and 39 deletions
@@ -1589,8 +1589,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
MOBILEGL_ASSERT(mipmapTexture != nullptr, "GenerateMipmap requires mipmap texture storage."); MOBILEGL_ASSERT(mipmapTexture != nullptr, "GenerateMipmap requires mipmap texture storage.");
Bool allocatedStorage = false; Bool allocatedStorage = false;
for (const TextureUploadTarget uploadTarget : texture->GetUploadTargets()) { for (const TextureUploadTarget uploadTarget : texture->GetUploadTargets()) {
MOBILEGL_ASSERT(EnsureGenerateMipmapStorageAllocated(*mipmapTexture, uploadTarget, allocatedStorage), const Bool allocated = EnsureGenerateMipmapStorageAllocated(*mipmapTexture, uploadTarget, allocatedStorage);
"GenerateMipmap could not allocate generated mipmap storage."); MOBILEGL_ASSERT(allocated, "GenerateMipmap could not allocate generated mipmap storage.");
} }
return allocatedStorage; return allocatedStorage;
} }
@@ -554,11 +554,79 @@ namespace MobileGL::MG_Backend::DirectGLES {
currentTextureInfo.mipmapLevels = mipmapCount; currentTextureInfo.mipmapLevels = mipmapCount;
Bool needsRegeneration = !m_isInitialized || (currentTextureInfo != m_prevTextureInfo); Bool needsRegeneration = !m_isInitialized || (currentTextureInfo != m_prevTextureInfo);
const Bool canAppendMipmaps =
m_isInitialized &&
currentTextureInfo.internalFormat == m_prevTextureInfo.internalFormat &&
currentTextureInfo.width == m_prevTextureInfo.width &&
currentTextureInfo.height == m_prevTextureInfo.height &&
currentTextureInfo.depth == m_prevTextureInfo.depth &&
currentTextureInfo.bufferExternalIndex == m_prevTextureInfo.bufferExternalIndex &&
currentTextureInfo.samples == m_prevTextureInfo.samples &&
currentTextureInfo.fixedSampleLocations == m_prevTextureInfo.fixedSampleLocations &&
currentTextureInfo.mipmapLevels > m_prevTextureInfo.mipmapLevels &&
!TextureImpl::IsMultisampleTextureTarget(targetInternal);
MGLOG_D("%s: Got texture info: %dx%dx%d, mips %d, format %s", __func__, baseSize.x(), baseSize.y(), MGLOG_D("%s: Got texture info: %dx%dx%d, mips %d, format %s", __func__, baseSize.x(), baseSize.y(),
baseSize.z(), mipmapCount, baseSize.z(), mipmapCount,
MG_Util::ConvertTextureInternalFormatToString(textureMipmapObject->GetFormat()).c_str()); MG_Util::ConvertTextureInternalFormatToString(textureMipmapObject->GetFormat()).c_str());
if (canAppendMipmaps) {
MGLOG_D("Texture mip count increased for backend ID %u, appending levels %zu..%zu",
m_backendTextureId, m_prevTextureInfo.mipmapLevels, mipmapCount - 1);
GLenum glInternalFormat, glType, glFormat;
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat,
&glFormat, &glType);
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
for (auto& uploadTarget : uploadTargets) {
for (SizeT level = m_prevTextureInfo.mipmapLevels; level < mipmapCount; ++level) {
auto levelTexelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level);
auto levelByteSize = textureMipmapObject->GetMipmapByteSize(uploadTarget, level);
bool levelDirty = textureMipmapObject->IsStorageDirty(uploadTarget, level);
auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget);
auto* pData = (levelDirty && levelByteSize != 0)
? textureMipmapObject->MapMipmapData(uploadTarget, level)
: nullptr;
DebugImpl::ErrorLopper::Clear();
g_GLESFuncs.glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
switch (stateTextureObject->GetTarget()) {
case TextureTarget::Texture2D:
case TextureTarget::TextureCubeMap:
g_GLESFuncs.glTexImage2D(
glUploadTarget, static_cast<GLint>(level), (GLint)glInternalFormat,
static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()),
0, glFormat, glType, pData);
break;
case TextureTarget::Texture3D:
g_GLESFuncs.glTexImage3D(
glUploadTarget, static_cast<GLint>(level), (GLint)glInternalFormat,
static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()),
static_cast<GLsizei>(levelTexelSize.z()), 0, glFormat, glType, pData);
break;
default:
MGLOG_E("Unhandled texture target %s",
MG_Util::ConvertTextureTargetToString(stateTextureObject->GetTarget()).c_str());
break;
}
DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__,
glUploadTarget, glInternalFormat, glFormat, glType,
pData](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s. glTexImage*: target=%s, internalformat=%s, format=%s, "
"type=%s, pixels=%p",
func, file, line, MG_Util::ConvertGLEnumToString(err).c_str(),
MG_Util::ConvertGLEnumToString(glUploadTarget).c_str(),
MG_Util::ConvertGLEnumToString(glInternalFormat).c_str(),
MG_Util::ConvertGLEnumToString(glFormat).c_str(),
MG_Util::ConvertGLEnumToString(glType).c_str(), pData);
});
textureMipmapObject->MarkStorageDirty(uploadTarget, level, false);
}
}
needsRegeneration = false;
}
if (needsRegeneration) { if (needsRegeneration) {
MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u", MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u",
m_backendTextureId); m_backendTextureId);
@@ -4212,8 +4212,9 @@ void main() {
static_cast<Int>(resource->format)); static_cast<Int>(resource->format));
} }
MOBILEGL_ASSERT(EnsureGenerateMipmapStorageAllocated(*mipmapTexture, uploadTarget, baseMipLevel), const Bool allocatedMipmapStorage =
"GenerateMipmap could not allocate a full mip chain for this texture."); EnsureGenerateMipmapStorageAllocated(*mipmapTexture, uploadTarget, baseMipLevel);
MOBILEGL_ASSERT(allocatedMipmapStorage, "GenerateMipmap could not allocate a full mip chain for this texture.");
resource = m_textureManager->SyncTextureAndGetDescriptor(*texture); resource = m_textureManager->SyncTextureAndGetDescriptor(*texture);
MOBILEGL_ASSERT(resource != nullptr && resource->image != VK_NULL_HANDLE, MOBILEGL_ASSERT(resource != nullptr && resource->image != VK_NULL_HANDLE,
@@ -2837,16 +2837,16 @@ namespace MobileGL::MG_Impl::GLImpl {
if (textureObject) { if (textureObject) {
auto* mipmapTexture = dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get()); auto* mipmapTexture = dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
MOBILEGL_ASSERT(mipmapTexture != nullptr, "GenerateMipmap requires mipmap texture storage."); MOBILEGL_ASSERT(mipmapTexture != nullptr, "GenerateMipmap requires mipmap texture storage.");
for (const TextureUploadTarget uploadTarget : textureObject->GetUploadTargets()) {
MOBILEGL_ASSERT(EnsureGeneratedMipmapStorageAllocated(*mipmapTexture, uploadTarget),
"GenerateMipmap could not allocate generated mipmap state.");
}
} }
GenerateMipmap_Backend(target); GenerateMipmap_Backend(target);
} }
void GenerateTextureMipmap(GLuint texture) { void GenerateTextureMipmap(GLuint texture) {
auto textureObject = GetTextureObjectByName(texture, __func__); auto textureObject = GetTextureObjectByName(texture, __func__);
if (textureObject) {
auto* mipmapTexture = dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(textureObject.get());
MOBILEGL_ASSERT(mipmapTexture != nullptr, "GenerateTextureMipmap requires mipmap texture storage.");
}
WithTemporarilyBoundNamedTexture(textureObject, [&](GLenum target) { GenerateMipmap_Backend(target); }); WithTemporarilyBoundNamedTexture(textureObject, [&](GLenum target) { GenerateMipmap_Backend(target); });
} }
@@ -66,6 +66,7 @@ namespace MobileGL::MG_State::GLState {
m_uniformLocations.clear(); m_uniformLocations.clear();
m_uniformIndexInTProgram.clear(); m_uniformIndexInTProgram.clear();
m_uniformSamplerOrImageUnitIndex.clear(); m_uniformSamplerOrImageUnitIndex.clear();
m_explicitOpaqueUniformBindings.clear();
m_uniformBlockIndexByName.clear(); m_uniformBlockIndexByName.clear();
m_uniformBlockBinding.clear(); m_uniformBlockBinding.clear();
m_uniformOffsets.clear(); m_uniformOffsets.clear();
@@ -199,7 +200,9 @@ namespace MobileGL::MG_State::GLState {
MG_Util::ShaderTranspiler::ProgramAttrib attrib{.shaders = Move(shaders), MG_Util::ShaderTranspiler::ProgramAttrib attrib{.shaders = Move(shaders),
.explicitVertexInLocations = m_explicitAttribLocations, .explicitVertexInLocations = m_explicitAttribLocations,
.explicitFragmentOutLocations = m_explicitFragDataLocation}; .explicitFragmentOutLocations = m_explicitFragDataLocation,
.explicitOpaqueUniformBindings =
&m_explicitOpaqueUniformBindings};
MGLOG_D("ProgramObject %u: Calling ShaderCompiler::LinkProgram", m_externalIndex); MGLOG_D("ProgramObject %u: Calling ShaderCompiler::LinkProgram", m_externalIndex);
auto result = MG_Util::ShaderTranspiler::ShaderCompiler::LinkProgram(attrib); auto result = MG_Util::ShaderTranspiler::ShaderCompiler::LinkProgram(attrib);
@@ -306,6 +309,11 @@ namespace MobileGL::MG_State::GLState {
} }
SizeT locNeedle = 0; SizeT locNeedle = 0;
std::sort(unallocatedUniformIndex.begin(), unallocatedUniformIndex.end(), [this](Int lhs, Int rhs) {
const auto& lhsUniform = m_program->getUniform(lhs);
const auto& rhsUniform = m_program->getUniform(rhs);
return lhsUniform.name < rhsUniform.name;
});
for (auto index : unallocatedUniformIndex) { for (auto index : unallocatedUniformIndex) {
auto& uniform = m_program->getUniform(index); auto& uniform = m_program->getUniform(index);
for (; locNeedle <= m_maxUniformLocation; locNeedle++) { for (; locNeedle <= m_maxUniformLocation; locNeedle++) {
@@ -334,12 +342,12 @@ namespace MobileGL::MG_State::GLState {
continue; continue;
} }
const int binding = uniform.getBinding(); const auto explicitBinding = m_explicitOpaqueUniformBindings.find(uniform.name);
if (binding >= 0 && binding != static_cast<int>(glslang::TQualifier::layoutBindingEnd)) { const int initialUnit =
m_uniformSamplerOrImageUnitIndex[location] = binding; explicitBinding != m_explicitOpaqueUniformBindings.end() ? static_cast<int>(explicitBinding->second) : 0;
MGLOG_D("ProgramObject %u: Reflection - opaque uniform '%s' location=%u initialUnit=%d", m_uniformSamplerOrImageUnitIndex[location] = initialUnit;
m_externalIndex, uniform.name.c_str(), location, binding); MGLOG_D("ProgramObject %u: Reflection - opaque uniform '%s' location=%u initialUnit=%d",
} m_externalIndex, uniform.name.c_str(), location, initialUnit);
} }
// ------------ attributes (vertex in) --------------- // ------------ attributes (vertex in) ---------------
@@ -461,7 +469,8 @@ namespace MobileGL::MG_State::GLState {
// 2. Do actual linking // 2. Do actual linking
ProgramAttrib attrib{.shaders = Move(shaders), ProgramAttrib attrib{.shaders = Move(shaders),
.explicitVertexInLocations = m_explicitAttribLocations, .explicitVertexInLocations = m_explicitAttribLocations,
.explicitFragmentOutLocations = m_explicitFragDataLocation}; .explicitFragmentOutLocations = m_explicitFragDataLocation,
.explicitOpaqueUniformBindings = &m_explicitOpaqueUniformBindings};
MGLOG_D("ProgramObject %u: GenerateBinary - linking program for binary", m_externalIndex); MGLOG_D("ProgramObject %u: GenerateBinary - linking program for binary", m_externalIndex);
auto programResult = ShaderCompiler::LinkProgram(attrib); auto programResult = ShaderCompiler::LinkProgram(attrib);
if (!programResult) { if (!programResult) {
@@ -495,6 +504,8 @@ namespace MobileGL::MG_State::GLState {
m_uniformSizesInBytes.clear(); m_uniformSizesInBytes.clear();
m_uniformOffsets.clear(); m_uniformOffsets.clear();
m_globalUboScratch.clear(); m_globalUboScratch.clear();
m_uniformOffsets.resize(m_maxUniformLocation + 1);
m_uniformSizesInBytes.resize(m_maxUniformLocation + 1);
for (SizeT i = 0; i < m_generatedSpirv.size(); i++) { for (SizeT i = 0; i < m_generatedSpirv.size(); i++) {
auto& spv = m_generatedSpirv[i]; auto& spv = m_generatedSpirv[i];
@@ -520,37 +531,34 @@ namespace MobileGL::MG_State::GLState {
if (size == 0) { if (size == 0) {
continue; continue;
} }
m_globalUboScratch.resize(size); if (m_globalUboScratch.size() < size) {
m_uniformOffsets.resize(m_maxUniformLocation + 1); m_globalUboScratch.resize(size);
}
for (const auto& [name, offset] : meta.plainUniformOffsetsInUBO) { 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; m_uniformOffsets[m_uniformLocations[name]] = offset;
MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' offset=%u assigned to location %u", MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' offset=%u assigned to location %u",
m_externalIndex, name.c_str(), offset, m_uniformLocations[name]); m_externalIndex, name.c_str(), offset, m_uniformLocations[name]);
} else { } else {
MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' offset=%u but not found in " MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' offset=%u but not found in "
"m_uniformLocations", "m_uniformLocations",
m_externalIndex, name.c_str(), offset); m_externalIndex, name.c_str(), offset);
} }
} }
m_uniformSizesInBytes.resize(m_maxUniformLocation + 1);
for (const auto& [name, size] : meta.plainUniformMemberSizesInBytes) { 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; m_uniformSizesInBytes[m_uniformLocations[name]] = size;
MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' size=%u assigned to location %u", MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' size=%u assigned to location %u",
m_externalIndex, name.c_str(), size, m_uniformLocations[name]); m_externalIndex, name.c_str(), size, m_uniformLocations[name]);
} else { } else {
MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' size=%u but not found in " MGLOG_D("ProgramObject %u: GenerateBinary - uniform '%s' size=%u but not found in "
"m_uniformLocations", "m_uniformLocations",
m_externalIndex, name.c_str(), size); m_externalIndex, name.c_str(), size);
} }
} }
// Only parse first module that contains uniform metadata MGLOG_D("ProgramObject %u: GenerateBinary - finished parsing module %zu metadata",
MGLOG_D("ProgramObject %u: GenerateBinary - finished parsing module %zu; breaking after first "
"valid metadata",
m_externalIndex, i); m_externalIndex, i);
} }
break;
} }
} }
@@ -162,7 +162,12 @@ namespace MobileGL::MG_State::GLState {
Uint32 GetBackendStateVersion() const { return m_backendStateVersion; } Uint32 GetBackendStateVersion() const { return m_backendStateVersion; }
void SetUniformSamplerOrImageUnitIndex(Uint location, Int unit) { void SetUniformSamplerOrImageUnitIndex(Uint location, Int unit) {
if (location >= m_uniformSamplerOrImageUnitIndex.size() ||
m_uniformSamplerOrImageUnitIndex[location] == unit) {
return;
}
m_uniformSamplerOrImageUnitIndex[location] = unit; m_uniformSamplerOrImageUnitIndex[location] = unit;
++m_backendStateVersion;
} }
Int GetUniformSamplerOrImageUnitIndex(Uint location) const { Int GetUniformSamplerOrImageUnitIndex(Uint location) const {
@@ -260,6 +265,7 @@ namespace MobileGL::MG_State::GLState {
Vector<Int> m_uniformIndexInTProgram; Vector<Int> m_uniformIndexInTProgram;
// ditto. Will be set at glUniform1i // ditto. Will be set at glUniform1i
Vector<Int> m_uniformSamplerOrImageUnitIndex; Vector<Int> m_uniformSamplerOrImageUnitIndex;
UnorderedMap<String, Uint> m_explicitOpaqueUniformBindings;
// Ordered by uniform block index // Ordered by uniform block index
// index is DIFFERENT from binding!!! // index is DIFFERENT from binding!!!
@@ -197,7 +197,8 @@ namespace MobileGL {
if (program->getIntermediate((EShLanguage)stage) == nullptr) continue; if (program->getIntermediate((EShLanguage)stage) == nullptr) continue;
resolver = resolver =
MakeUnique<TMglGlslIoResolver>(*program, (EShLanguage)stage, attrib.explicitVertexInLocations, MakeUnique<TMglGlslIoResolver>(*program, (EShLanguage)stage, attrib.explicitVertexInLocations,
attrib.explicitFragmentOutLocations); attrib.explicitFragmentOutLocations,
attrib.explicitOpaqueUniformBindings);
break; break;
} }
auto ioMapper = UniquePtr<glslang::TIoMapper>(glslang::GetGlslIoMapper()); auto ioMapper = UniquePtr<glslang::TIoMapper>(glslang::GetGlslIoMapper());
@@ -235,6 +236,8 @@ namespace MobileGL {
Optimizer optimizer(SPV_ENV_VULKAN_1_1); Optimizer optimizer(SPV_ENV_VULKAN_1_1);
optimizer.RegisterPass(CreateAggressiveDCEPass(false));
optimizer.RegisterPass(CreateRemoveUnusedInterfaceVariablesPass());
optimizer.RegisterPass(FlattenInterfaceStructPass::CreateFlattenInterfaceStructPass()); optimizer.RegisterPass(FlattenInterfaceStructPass::CreateFlattenInterfaceStructPass());
optimizer.RegisterPass(EliminateFloatEqualsZeroPass::CreateEliminateFloatEqualsZeroPass()); optimizer.RegisterPass(EliminateFloatEqualsZeroPass::CreateEliminateFloatEqualsZeroPass());
@@ -31,6 +31,7 @@ namespace MobileGL {
Vector<SharedPtr<glslang::TShader>> shaders; Vector<SharedPtr<glslang::TShader>> shaders;
UnorderedMap<String, Uint> explicitVertexInLocations; UnorderedMap<String, Uint> explicitVertexInLocations;
UnorderedMap<String, Uint> explicitFragmentOutLocations; UnorderedMap<String, Uint> explicitFragmentOutLocations;
UnorderedMap<String, Uint>* explicitOpaqueUniformBindings = nullptr;
}; };
struct ProgramBinaryAttrib { struct ProgramBinaryAttrib {
@@ -13,6 +13,53 @@
#include "TMglGlslIoResolver.h" #include "TMglGlslIoResolver.h"
namespace MobileGL { namespace MobileGL {
bool TMglGlslIoResolver::ShouldAssignPlainUniformLocation(const glslang::TType& type) const {
if (!doAutoLocationMapping()) {
return false;
}
if (type.getQualifier().hasLocation()) {
return false;
}
if (type.isBuiltIn() || type.getBasicType() == glslang::EbtBlock || type.isAtomic() || type.isSpirvType() ||
(type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
return false;
}
if (type.isStruct()) {
if (type.getStruct()->size() < 1) {
return false;
}
if ((*type.getStruct())[0].type->isBuiltIn()) {
return false;
}
}
return true;
}
void TMglGlslIoResolver::EnsurePlainUniformLocationsAssigned() {
if (m_plainUniformLocationsAssigned) {
return;
}
m_plainUniformLocationsAssigned = true;
const int resourceKey = buildStorageKey(EShLangCount, glslang::EvqUniform);
auto& slotMap = storageSlotMap[resourceKey];
for (const auto& [name, size] : m_plainUniformLocationSizeByName) {
const auto existingLocation = slotMap.find(name);
if (existingLocation != slotMap.end()) {
m_plainUniformLocationByName[name] = existingLocation->second;
continue;
}
const int location = getFreeSlot(resourceKey, 0, size);
slotMap[name] = location;
m_plainUniformLocationByName[name] = location;
}
}
void TMglGlslIoResolver::reserverStorageSlot(glslang::TVarEntryInfo& ent, TInfoSink& infoSink) { void TMglGlslIoResolver::reserverStorageSlot(glslang::TVarEntryInfo& ent, TInfoSink& infoSink) {
const glslang::TType& type = ent.symbol->getType(); const glslang::TType& type = ent.symbol->getType();
const glslang::TString& name = ent.symbol->getAccessName(); const glslang::TString& name = ent.symbol->getAccessName();
@@ -30,6 +77,43 @@ namespace MobileGL {
writableType.getQualifier().layoutLocation = it->second; writableType.getQualifier().layoutLocation = it->second;
} }
} }
if (ShouldAssignPlainUniformLocation(type)) {
const int size = glslang::TIntermediate::computeTypeUniformLocationSize(type);
auto& recordedSize = m_plainUniformLocationSizeByName[name];
recordedSize = std::max(recordedSize, size);
}
TDefaultGlslIoResolver::reserverStorageSlot(ent, infoSink); TDefaultGlslIoResolver::reserverStorageSlot(ent, infoSink);
} }
} // namespace MobileGL
void TMglGlslIoResolver::reserverResourceSlot(glslang::TVarEntryInfo& ent, TInfoSink& infoSink) {
const glslang::TType& type = ent.symbol->getType();
if (m_explicitOpaqueUniformBindings != nullptr && type.getBasicType() == glslang::EbtSampler &&
type.getQualifier().hasBinding()) {
const glslang::TString& name = ent.symbol->getAccessName();
(*m_explicitOpaqueUniformBindings)[name.c_str()] = type.getQualifier().layoutBinding;
}
TDefaultGlslIoResolver::reserverResourceSlot(ent, infoSink);
}
int TMglGlslIoResolver::resolveUniformLocation(EShLanguage stage, glslang::TVarEntryInfo& ent) {
const glslang::TType& type = ent.symbol->getType();
if (type.getQualifier().hasLocation()) {
return TDefaultGlslIoResolver::resolveUniformLocation(stage, ent);
}
if (!ShouldAssignPlainUniformLocation(type)) {
return TDefaultGlslIoResolver::resolveUniformLocation(stage, ent);
}
EnsurePlainUniformLocationsAssigned();
const glslang::TString& name = ent.symbol->getAccessName();
const auto location = m_plainUniformLocationByName.find(name);
if (location == m_plainUniformLocationByName.end()) {
return ent.newLocation = -1;
}
return ent.newLocation = location->second;
}
} // namespace MobileGL
@@ -26,15 +26,26 @@ namespace MobileGL {
public: public:
using ExplicitVarSlotMap = UnorderedMap<String, Uint>; using ExplicitVarSlotMap = UnorderedMap<String, Uint>;
TMglGlslIoResolver(const glslang::TIntermediate& intermediate, const ExplicitVarSlotMap& vertexIns, TMglGlslIoResolver(const glslang::TIntermediate& intermediate, const ExplicitVarSlotMap& vertexIns,
const ExplicitVarSlotMap& fragOuts) const ExplicitVarSlotMap& fragOuts, ExplicitVarSlotMap* opaqueUniformBindings)
: TDefaultGlslIoResolver(intermediate), m_explicitVertexIns(vertexIns), m_explicitFragOuts(fragOuts) {} : TDefaultGlslIoResolver(intermediate), m_explicitVertexIns(vertexIns), m_explicitFragOuts(fragOuts),
m_explicitOpaqueUniformBindings(opaqueUniformBindings) {}
TMglGlslIoResolver(const glslang::TProgram& program, const EShLanguage stage, TMglGlslIoResolver(const glslang::TProgram& program, const EShLanguage stage,
const ExplicitVarSlotMap& vertexIns, const ExplicitVarSlotMap& fragOuts) const ExplicitVarSlotMap& vertexIns, const ExplicitVarSlotMap& fragOuts,
: TMglGlslIoResolver(*program.getIntermediate(stage), vertexIns, fragOuts) {} ExplicitVarSlotMap* opaqueUniformBindings)
: TMglGlslIoResolver(*program.getIntermediate(stage), vertexIns, fragOuts, opaqueUniformBindings) {}
void reserverStorageSlot(glslang::TVarEntryInfo& ent, TInfoSink& infoSink) override; void reserverStorageSlot(glslang::TVarEntryInfo& ent, TInfoSink& infoSink) override;
void reserverResourceSlot(glslang::TVarEntryInfo& ent, TInfoSink& infoSink) override;
int resolveUniformLocation(EShLanguage stage, glslang::TVarEntryInfo& ent) override;
protected: protected:
bool ShouldAssignPlainUniformLocation(const glslang::TType& type) const;
void EnsurePlainUniformLocationsAssigned();
const ExplicitVarSlotMap& m_explicitVertexIns; const ExplicitVarSlotMap& m_explicitVertexIns;
const ExplicitVarSlotMap& m_explicitFragOuts; const ExplicitVarSlotMap& m_explicitFragOuts;
ExplicitVarSlotMap* m_explicitOpaqueUniformBindings = nullptr;
std::map<glslang::TString, int> m_plainUniformLocationSizeByName;
std::map<glslang::TString, int> m_plainUniformLocationByName;
bool m_plainUniformLocationsAssigned = false;
}; };
} // namespace MobileGL } // namespace MobileGL
+10
View File
@@ -445,6 +445,16 @@ add_trace_replay_test_for_backends(minecraft-1.21.4-fabric-iris-mellow-in-world
TOLERANCE 20 TOLERANCE 20
FUZZ_PERCENT 20) FUZZ_PERCENT 20)
add_trace_replay_test_for_backends(minecraft-1.21.4-fabric-iris-chocapic-v6-lite-in-world
TRACE_ARCHIVE ${MOBILEGL_TRACE_ROOT}/fixtures/minecraft-1.21.4-fabric-iris-chocapic-v6-lite-in-world.tgz
TRACE_FILE trace.trace
GOLDEN ${MOBILEGL_TRACE_ROOT}/fixtures/minecraft-1.21.4-fabric-iris-chocapic-v6-lite-in-world.0000125124.png
TARGET_CALL 125124
WIDTH 854
HEIGHT 480
TOLERANCE 700
FUZZ_PERCENT 20)
add_trace_replay_test_for_backends(minecraft-1.21.4-fabric-iris-iterationt-in-world add_trace_replay_test_for_backends(minecraft-1.21.4-fabric-iris-iterationt-in-world
TRACE_ARCHIVE ${MOBILEGL_TRACE_ROOT}/fixtures/minecraft-1.21.4-fabric-iris-iterationt-in-world.tgz TRACE_ARCHIVE ${MOBILEGL_TRACE_ROOT}/fixtures/minecraft-1.21.4-fabric-iris-iterationt-in-world.tgz
TRACE_FILE trace.trace TRACE_FILE trace.trace