HLSL: Fix #1249: Always execute both sides of ternary "?:".
This is semantically required by HLSL, and frequently results in using OpSelect instead of control flow.
This commit is contained in:
parent
a5cae08259
commit
4bee531fc1
17 changed files with 776 additions and 850 deletions
|
|
@ -1336,9 +1336,11 @@ class TIntermSelection : public TIntermTyped {
|
|||
public:
|
||||
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
|
||||
TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB),
|
||||
shortCircuit(true),
|
||||
flatten(false), dontFlatten(false) {}
|
||||
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
|
||||
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB),
|
||||
shortCircuit(true),
|
||||
flatten(false), dontFlatten(false) {}
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
virtual TIntermTyped* getCondition() const { return condition; }
|
||||
|
|
@ -1347,6 +1349,9 @@ public:
|
|||
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
||||
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
|
||||
|
||||
void setNoShortCircuit() { shortCircuit = false; }
|
||||
bool getShortCircuit() const { return shortCircuit; }
|
||||
|
||||
void setFlatten() { flatten = true; }
|
||||
void setDontFlatten() { dontFlatten = true; }
|
||||
bool getFlatten() const { return flatten; }
|
||||
|
|
@ -1356,8 +1361,9 @@ protected:
|
|||
TIntermTyped* condition;
|
||||
TIntermNode* trueBlock;
|
||||
TIntermNode* falseBlock;
|
||||
bool flatten; // true if flatten requested
|
||||
bool dontFlatten; // true if requested to not flatten
|
||||
bool shortCircuit; // normally all if-then-else and all GLSL ?: short-circuit, but HLSL ?: does not
|
||||
bool flatten; // true if flatten requested
|
||||
bool dontFlatten; // true if requested to not flatten
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1672,7 +1672,11 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
|
|||
// If it's void, go to the if-then-else selection()
|
||||
if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) {
|
||||
TIntermNodePair pair = { trueBlock, falseBlock };
|
||||
return addSelection(cond, pair, loc);
|
||||
TIntermSelection* selection = addSelection(cond, pair, loc);
|
||||
if (getSource() == EShSourceHlsl)
|
||||
selection->setNoShortCircuit();
|
||||
|
||||
return selection;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1743,6 +1747,9 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
|
|||
else
|
||||
node->getQualifier().makeTemporary();
|
||||
|
||||
if (getSource() == EShSourceHlsl)
|
||||
node->setNoShortCircuit();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -819,6 +819,8 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node
|
|||
out.debug << "Test condition and select";
|
||||
out.debug << " (" << node->getCompleteString() << ")";
|
||||
|
||||
if (node->getShortCircuit() == false)
|
||||
out.debug << ": no shortcircuit";
|
||||
if (node->getFlatten())
|
||||
out.debug << ": Flatten";
|
||||
if (node->getDontFlatten())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue