mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-10 12:30:05 +00:00
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.
This commit is contained in:
parent
2fb966aad2
commit
b239d22f7b
@ -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();
|
|
||||||
if (!symbol)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler());
|
// qual and seq are indexed using the same indices, so we have to modify both in lock-step
|
||||||
});
|
assert(seq.size() == qual.size() || qual.empty());
|
||||||
seq.erase(newEnd, seq.end());
|
|
||||||
// replace constructors with sampler/textures
|
size_t write = 0;
|
||||||
for_each(seq.begin(), seq.end(), [](TIntermNode*& node) {
|
for (size_t i = 0; i < seq.size(); ++i) {
|
||||||
TIntermAggregate *constructor = node->getAsAggregate();
|
TIntermSymbol* symbol = seq[i]->getAsSymbolNode();
|
||||||
|
if (symbol && symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler()) {
|
||||||
|
// remove pure sampler variables
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TIntermNode* result = seq[i];
|
||||||
|
|
||||||
|
// replace constructors with sampler/textures
|
||||||
|
TIntermAggregate *constructor = seq[i]->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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user