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.
This commit is contained in:
parent
b481744aea
commit
5727fb313e
@ -74,14 +74,33 @@ public:
|
|||||||
for (unsigned int f = 0; f < globals.size(); ++f) {
|
for (unsigned int f = 0; f < globals.size(); ++f) {
|
||||||
TIntermAggregate* candidate = globals[f]->getAsAggregate();
|
TIntermAggregate* candidate = globals[f]->getAsAggregate();
|
||||||
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
|
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
|
||||||
functions.push_back(candidate);
|
destinations.push_back(candidate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::list<TIntermAggregate*> TFunctionStack;
|
void pushGlobalReference(const TString& name)
|
||||||
TFunctionStack functions;
|
{
|
||||||
|
TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence();
|
||||||
|
for (unsigned int f = 0; f < globals.size(); ++f) {
|
||||||
|
TIntermAggregate* candidate = globals[f]->getAsAggregate();
|
||||||
|
if (candidate && candidate->getOp() == EOpSequence &&
|
||||||
|
candidate->getSequence().size() == 1 &&
|
||||||
|
candidate->getSequence()[0]->getAsBinaryNode()) {
|
||||||
|
TIntermBinary* binary = candidate->getSequence()[0]->getAsBinaryNode();
|
||||||
|
TIntermSymbol* symbol = binary->getLeft()->getAsSymbolNode();
|
||||||
|
if (symbol && symbol->getQualifier().storage == EvqGlobal &&
|
||||||
|
symbol->getName() == name) {
|
||||||
|
destinations.push_back(candidate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::list<TIntermAggregate*> TDestinationStack;
|
||||||
|
TDestinationStack destinations;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// To catch which function calls are not dead, and hence which functions must be visited.
|
// To catch which function calls are not dead, and hence which functions must be visited.
|
||||||
@ -117,16 +136,27 @@ protected:
|
|||||||
// and only visit each function once.
|
// and only visit each function once.
|
||||||
void addFunctionCall(TIntermAggregate* call)
|
void addFunctionCall(TIntermAggregate* call)
|
||||||
{
|
{
|
||||||
// // just use the map to ensure we process each function at most once
|
// just use the map to ensure we process each function at most once
|
||||||
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
|
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
|
||||||
liveFunctions.insert(call->getName());
|
liveFunctions.insert(call->getName());
|
||||||
pushFunction(call->getName());
|
pushFunction(call->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addGlobalReference(const TString& name)
|
||||||
|
{
|
||||||
|
// just use the map to ensure we process each global at most once
|
||||||
|
if (liveGlobals.find(name) == liveGlobals.end()) {
|
||||||
|
liveGlobals.insert(name);
|
||||||
|
pushGlobalReference(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const TIntermediate& intermediate;
|
const TIntermediate& intermediate;
|
||||||
typedef std::unordered_set<TString> TLiveFunctions;
|
typedef std::unordered_set<TString> TLiveFunctions;
|
||||||
TLiveFunctions liveFunctions;
|
TLiveFunctions liveFunctions;
|
||||||
|
typedef std::unordered_set<TString> TLiveGlobals;
|
||||||
|
TLiveGlobals liveGlobals;
|
||||||
bool traverseAll;
|
bool traverseAll;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -79,6 +79,11 @@ public:
|
|||||||
target = &outputList;
|
target = &outputList;
|
||||||
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
|
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
|
||||||
target = &uniformList;
|
target = &uniformList;
|
||||||
|
// If a global is being visited, then we should also traverse it incase it's evaluation
|
||||||
|
// ends up visiting inputs we want to tag as live
|
||||||
|
else if (base->getQualifier().storage == EvqGlobal)
|
||||||
|
addGlobalReference(base->getName());
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
|
TVarEntryInfo ent = {base->getId(), base, ! traverseAll};
|
||||||
ent.stage = intermediate.getStage();
|
ent.stage = intermediate.getStage();
|
||||||
@ -1105,11 +1110,12 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
|
|||||||
TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
|
TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
|
||||||
root->traverse(&iter_binding_all);
|
root->traverse(&iter_binding_all);
|
||||||
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
||||||
while (! iter_binding_live.functions.empty()) {
|
while (! iter_binding_live.destinations.empty()) {
|
||||||
TIntermNode* function = iter_binding_live.functions.back();
|
TIntermNode* destination = iter_binding_live.destinations.back();
|
||||||
iter_binding_live.functions.pop_back();
|
iter_binding_live.destinations.pop_back();
|
||||||
function->traverse(&iter_binding_live);
|
destination->traverse(&iter_binding_live);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
|
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
|
||||||
std::for_each(inVarMap.begin(), inVarMap.end(),
|
std::for_each(inVarMap.begin(), inVarMap.end(),
|
||||||
[&inVector](TVarLivePair p) { inVector.push_back(p); });
|
[&inVector](TVarLivePair p) { inVector.push_back(p); });
|
||||||
@ -1200,11 +1206,12 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn
|
|||||||
*uniformVarMap[stage]);
|
*uniformVarMap[stage]);
|
||||||
root->traverse(&iter_binding_all);
|
root->traverse(&iter_binding_all);
|
||||||
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
||||||
while (! iter_binding_live.functions.empty()) {
|
while (! iter_binding_live.destinations.empty()) {
|
||||||
TIntermNode* function = iter_binding_live.functions.back();
|
TIntermNode* destination = iter_binding_live.destinations.back();
|
||||||
iter_binding_live.functions.pop_back();
|
iter_binding_live.destinations.pop_back();
|
||||||
function->traverse(&iter_binding_live);
|
destination->traverse(&iter_binding_live);
|
||||||
}
|
}
|
||||||
|
|
||||||
TNotifyInOutAdaptor inOutNotify(stage, *resolver);
|
TNotifyInOutAdaptor inOutNotify(stage, *resolver);
|
||||||
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
|
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
|
||||||
// Resolve current stage input symbol location with previous stage output here,
|
// Resolve current stage input symbol location with previous stage output here,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user