GLSL/SPV: Propagaet precision qualifier from function to return value.
When a return value's type has no precision qualification (e.g., the return expression is formed from a constructor), and the formal function return type has a precision qualification, back propagate that from the return type to the type of the return value's expression.
This commit is contained in:
parent
4f72970ed3
commit
3d2391fb25
7 changed files with 462 additions and 455 deletions
|
|
@ -2777,6 +2777,22 @@ TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expres
|
|||
return node;
|
||||
}
|
||||
|
||||
// Propagate precision from formal function return type to actual return type,
|
||||
// and on to its subtree.
|
||||
void TIntermBranch::updatePrecision(TPrecisionQualifier parentPrecision)
|
||||
{
|
||||
TIntermTyped* exp = getExpression();
|
||||
if (exp == nullptr)
|
||||
return;
|
||||
|
||||
if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint ||
|
||||
exp->getBasicType() == EbtFloat || exp->getBasicType() == EbtFloat16) {
|
||||
if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) {
|
||||
exp->propagatePrecision(parentPrecision);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// This is to be executed after the final root is put on top by the parsing
|
||||
// process.
|
||||
|
|
@ -3284,9 +3300,11 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Propagate precision qualifiers *up* from children to parent.
|
||||
void TIntermUnary::updatePrecision()
|
||||
{
|
||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
||||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
||||
if (operand->getQualifier().precision > getQualifier().precision)
|
||||
getQualifier().precision = operand->getQualifier().precision;
|
||||
}
|
||||
|
|
@ -3782,9 +3800,12 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Propagate precision qualifiers *up* from children to parent, and then
|
||||
// back *down* again to the children's subtrees.
|
||||
void TIntermBinary::updatePrecision()
|
||||
{
|
||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
||||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
||||
getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
|
||||
if (getQualifier().precision != EpqNone) {
|
||||
left->propagatePrecision(getQualifier().precision);
|
||||
|
|
@ -3793,9 +3814,14 @@ void TIntermBinary::updatePrecision()
|
|||
}
|
||||
}
|
||||
|
||||
// Recursively propagate precision qualifiers *down* the subtree of the current node,
|
||||
// until reaching a node that already has a precision qualifier or otherwise does
|
||||
// not participate in precision propagation.
|
||||
void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision)
|
||||
{
|
||||
if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat && getBasicType() != EbtFloat16))
|
||||
if (getQualifier().precision != EpqNone ||
|
||||
(getBasicType() != EbtInt && getBasicType() != EbtUint &&
|
||||
getBasicType() != EbtFloat && getBasicType() != EbtFloat16))
|
||||
return;
|
||||
|
||||
getQualifier().precision = newPrecision;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue