mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[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:
@@ -197,7 +197,8 @@ namespace MobileGL {
|
||||
if (program->getIntermediate((EShLanguage)stage) == nullptr) continue;
|
||||
resolver =
|
||||
MakeUnique<TMglGlslIoResolver>(*program, (EShLanguage)stage, attrib.explicitVertexInLocations,
|
||||
attrib.explicitFragmentOutLocations);
|
||||
attrib.explicitFragmentOutLocations,
|
||||
attrib.explicitOpaqueUniformBindings);
|
||||
break;
|
||||
}
|
||||
auto ioMapper = UniquePtr<glslang::TIoMapper>(glslang::GetGlslIoMapper());
|
||||
@@ -235,6 +236,8 @@ namespace MobileGL {
|
||||
|
||||
Optimizer optimizer(SPV_ENV_VULKAN_1_1);
|
||||
|
||||
optimizer.RegisterPass(CreateAggressiveDCEPass(false));
|
||||
optimizer.RegisterPass(CreateRemoveUnusedInterfaceVariablesPass());
|
||||
optimizer.RegisterPass(FlattenInterfaceStructPass::CreateFlattenInterfaceStructPass());
|
||||
optimizer.RegisterPass(EliminateFloatEqualsZeroPass::CreateEliminateFloatEqualsZeroPass());
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace MobileGL {
|
||||
Vector<SharedPtr<glslang::TShader>> shaders;
|
||||
UnorderedMap<String, Uint> explicitVertexInLocations;
|
||||
UnorderedMap<String, Uint> explicitFragmentOutLocations;
|
||||
UnorderedMap<String, Uint>* explicitOpaqueUniformBindings = nullptr;
|
||||
};
|
||||
|
||||
struct ProgramBinaryAttrib {
|
||||
|
||||
@@ -13,6 +13,53 @@
|
||||
#include "TMglGlslIoResolver.h"
|
||||
|
||||
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) {
|
||||
const glslang::TType& type = ent.symbol->getType();
|
||||
const glslang::TString& name = ent.symbol->getAccessName();
|
||||
@@ -30,6 +77,43 @@ namespace MobileGL {
|
||||
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);
|
||||
}
|
||||
} // 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:
|
||||
using ExplicitVarSlotMap = UnorderedMap<String, Uint>;
|
||||
TMglGlslIoResolver(const glslang::TIntermediate& intermediate, const ExplicitVarSlotMap& vertexIns,
|
||||
const ExplicitVarSlotMap& fragOuts)
|
||||
: TDefaultGlslIoResolver(intermediate), m_explicitVertexIns(vertexIns), m_explicitFragOuts(fragOuts) {}
|
||||
const ExplicitVarSlotMap& fragOuts, ExplicitVarSlotMap* opaqueUniformBindings)
|
||||
: TDefaultGlslIoResolver(intermediate), m_explicitVertexIns(vertexIns), m_explicitFragOuts(fragOuts),
|
||||
m_explicitOpaqueUniformBindings(opaqueUniformBindings) {}
|
||||
TMglGlslIoResolver(const glslang::TProgram& program, const EShLanguage stage,
|
||||
const ExplicitVarSlotMap& vertexIns, const ExplicitVarSlotMap& fragOuts)
|
||||
: TMglGlslIoResolver(*program.getIntermediate(stage), vertexIns, fragOuts) {}
|
||||
const ExplicitVarSlotMap& vertexIns, const ExplicitVarSlotMap& fragOuts,
|
||||
ExplicitVarSlotMap* opaqueUniformBindings)
|
||||
: TMglGlslIoResolver(*program.getIntermediate(stage), vertexIns, fragOuts, opaqueUniformBindings) {}
|
||||
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:
|
||||
bool ShouldAssignPlainUniformLocation(const glslang::TType& type) const;
|
||||
void EnsurePlainUniformLocationsAssigned();
|
||||
|
||||
const ExplicitVarSlotMap& m_explicitVertexIns;
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user