Skip to content

Commit 5727fb3

Browse files
committed
also search global variables assignment for live variables
when traversing the AST to find live UBOs etc, also traverse references to global module-level variables, incase they are being filled in from UBOs etc.
1 parent b481744 commit 5727fb3

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

glslang/MachineIndependent/LiveTraverser.h

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,33 @@ class TLiveTraverser : public TIntermTraverser {
7474
for (unsigned int f = 0; f < globals.size(); ++f) {
7575
TIntermAggregate* candidate = globals[f]->getAsAggregate();
7676
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
77-
functions.push_back(candidate);
77+
destinations.push_back(candidate);
7878
break;
7979
}
8080
}
8181
}
8282

83-
typedef std::list<TIntermAggregate*> TFunctionStack;
84-
TFunctionStack functions;
83+
void pushGlobalReference(const TString& name)
84+
{
85+
TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence();
86+
for (unsigned int f = 0; f < globals.size(); ++f) {
87+
TIntermAggregate* candidate = globals[f]->getAsAggregate();
88+
if (candidate && candidate->getOp() == EOpSequence &&
89+
candidate->getSequence().size() == 1 &&
90+
candidate->getSequence()[0]->getAsBinaryNode()) {
91+
TIntermBinary* binary = candidate->getSequence()[0]->getAsBinaryNode();
92+
TIntermSymbol* symbol = binary->getLeft()->getAsSymbolNode();
93+
if (symbol && symbol->getQualifier().storage == EvqGlobal &&
94+
symbol->getName() == name) {
95+
destinations.push_back(candidate);
96+
break;
97+
}
98+
}
99+
}
100+
}
101+
102+
typedef std::list<TIntermAggregate*> TDestinationStack;
103+
TDestinationStack destinations;
85104

86105
protected:
87106
// To catch which function calls are not dead, and hence which functions must be visited.
@@ -117,16 +136,27 @@ class TLiveTraverser : public TIntermTraverser {
117136
// and only visit each function once.
118137
void addFunctionCall(TIntermAggregate* call)
119138
{
120-
// // just use the map to ensure we process each function at most once
139+
// just use the map to ensure we process each function at most once
121140
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
122141
liveFunctions.insert(call->getName());
123142
pushFunction(call->getName());
124143
}
125144
}
126145

146+
void addGlobalReference(const TString& name)
147+
{
148+
// just use the map to ensure we process each global at most once
149+
if (liveGlobals.find(name) == liveGlobals.end()) {
150+
liveGlobals.insert(name);
151+
pushGlobalReference(name);
152+
}
153+
}
154+
127155
const TIntermediate& intermediate;
128156
typedef std::unordered_set<TString> TLiveFunctions;
129157
TLiveFunctions liveFunctions;
158+
typedef std::unordered_set<TString> TLiveGlobals;
159+
TLiveGlobals liveGlobals;
130160
bool traverseAll;
131161

132162
private:

glslang/MachineIndependent/iomapper.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ class TVarGatherTraverser : public TLiveTraverser {
7979
target = &outputList;
8080
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
8181
target = &uniformList;
82+
// If a global is being visited, then we should also traverse it incase it's evaluation
83+
// ends up visiting inputs we want to tag as live
84+
else if (base->getQualifier().storage == EvqGlobal)
85+
addGlobalReference(base->getName());
86+
8287
if (target) {
8388
TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
8489
ent.stage = intermediate.getStage();
@@ -1105,11 +1110,12 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
11051110
TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
11061111
root->traverse(&iter_binding_all);
11071112
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
1108-
while (! iter_binding_live.functions.empty()) {
1109-
TIntermNode* function = iter_binding_live.functions.back();
1110-
iter_binding_live.functions.pop_back();
1111-
function->traverse(&iter_binding_live);
1113+
while (! iter_binding_live.destinations.empty()) {
1114+
TIntermNode* destination = iter_binding_live.destinations.back();
1115+
iter_binding_live.destinations.pop_back();
1116+
destination->traverse(&iter_binding_live);
11121117
}
1118+
11131119
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
11141120
std::for_each(inVarMap.begin(), inVarMap.end(),
11151121
[&inVector](TVarLivePair p) { inVector.push_back(p); });
@@ -1200,11 +1206,12 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn
12001206
*uniformVarMap[stage]);
12011207
root->traverse(&iter_binding_all);
12021208
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
1203-
while (! iter_binding_live.functions.empty()) {
1204-
TIntermNode* function = iter_binding_live.functions.back();
1205-
iter_binding_live.functions.pop_back();
1206-
function->traverse(&iter_binding_live);
1209+
while (! iter_binding_live.destinations.empty()) {
1210+
TIntermNode* destination = iter_binding_live.destinations.back();
1211+
iter_binding_live.destinations.pop_back();
1212+
destination->traverse(&iter_binding_live);
12071213
}
1214+
12081215
TNotifyInOutAdaptor inOutNotify(stage, *resolver);
12091216
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
12101217
// Resolve current stage input symbol location with previous stage output here,

0 commit comments

Comments
 (0)