Commit b239d22f by Arseny Kapoulkine

Fix TextureUpgradeAndSamplerRemovalTransform when used with qualifiers

The transform removes sampler arguments from functions and function calls; this causes function arguments to change their indices. When some function arguments have an output qualifier, this qualifier can get lost because of the removal which can lead to incorrect results (e.g. out qualifier not having effect). To fix this we iterate through both seq & qual arrays in lock-step and manually remove/replace entries as appropriate.
parent 2fb966aa
...@@ -3769,23 +3769,39 @@ struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser { ...@@ -3769,23 +3769,39 @@ struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser {
bool visitAggregate(TVisit, TIntermAggregate* ag) override { bool visitAggregate(TVisit, TIntermAggregate* ag) override {
using namespace std; using namespace std;
TIntermSequence& seq = ag->getSequence(); TIntermSequence& seq = ag->getSequence();
// remove pure sampler variables TQualifierList& qual = ag->getQualifierList();
TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) {
TIntermSymbol* symbol = node->getAsSymbolNode(); // qual and seq are indexed using the same indices, so we have to modify both in lock-step
if (!symbol) assert(seq.size() == qual.size() || qual.empty());
return false;
size_t write = 0;
for (size_t i = 0; i < seq.size(); ++i) {
TIntermSymbol* symbol = seq[i]->getAsSymbolNode();
if (symbol && symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler()) {
// remove pure sampler variables
continue;
}
TIntermNode* result = seq[i];
return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler()); // replace constructors with sampler/textures
}); TIntermAggregate *constructor = seq[i]->getAsAggregate();
seq.erase(newEnd, seq.end());
// replace constructors with sampler/textures
for_each(seq.begin(), seq.end(), [](TIntermNode*& node) {
TIntermAggregate *constructor = node->getAsAggregate();
if (constructor && constructor->getOp() == EOpConstructTextureSampler) { if (constructor && constructor->getOp() == EOpConstructTextureSampler) {
if (!constructor->getSequence().empty()) if (!constructor->getSequence().empty())
node = constructor->getSequence()[0]; result = constructor->getSequence()[0];
} }
});
// write new node & qualifier
seq[write] = result;
if (!qual.empty())
qual[write] = qual[i];
write++;
}
seq.resize(write);
if (!qual.empty())
qual.resize(write);
return true; return true;
} }
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment