Unverified Commit f3cb1896 by John Kessenich Committed by GitHub

Merge pull request #2349 from KhronosGroup/return-precision

GLSL/SPV: Propagaet precision qualifier from function to return value.
parents 4f72970e 3d2391fb
...@@ -61,7 +61,7 @@ ERROR: node is still EOpNull! ...@@ -61,7 +61,7 @@ ERROR: node is still EOpNull!
0:49 Constant: 0:49 Constant:
0:49 0.000000 0:49 0.000000
0:50 Branch: Return with expression 0:50 Branch: Return with expression
0:50 Construct float ( temp 4-element array of 7-element array of float) 0:50 Construct float ( temp 4-element array of 7-element array of highp float)
0:50 direct index ( temp 7-element array of highp float) 0:50 direct index ( temp 7-element array of highp float)
0:50 'a' ( in 5-element array of 7-element array of highp float) 0:50 'a' ( in 5-element array of 7-element array of highp float)
0:50 Constant: 0:50 Constant:
...@@ -76,7 +76,7 @@ ERROR: node is still EOpNull! ...@@ -76,7 +76,7 @@ ERROR: node is still EOpNull!
0:50 Constant: 0:50 Constant:
0:50 3 (const int) 0:50 3 (const int)
0:51 Branch: Return with expression 0:51 Branch: Return with expression
0:51 Construct float ( temp 4-element array of 7-element array of float) 0:51 Construct float ( temp 4-element array of 7-element array of highp float)
0:51 direct index ( temp 7-element array of highp float) 0:51 direct index ( temp 7-element array of highp float)
0:51 'a' ( in 5-element array of 7-element array of highp float) 0:51 'a' ( in 5-element array of 7-element array of highp float)
0:51 Constant: 0:51 Constant:
...@@ -91,7 +91,7 @@ ERROR: node is still EOpNull! ...@@ -91,7 +91,7 @@ ERROR: node is still EOpNull!
0:51 Constant: 0:51 Constant:
0:51 3 (const int) 0:51 3 (const int)
0:52 Branch: Return with expression 0:52 Branch: Return with expression
0:52 Construct float ( temp 4-element array of 7-element array of float) 0:52 Construct float ( temp 4-element array of 7-element array of highp float)
0:52 direct index ( temp 7-element array of highp float) 0:52 direct index ( temp 7-element array of highp float)
0:52 'a' ( in 5-element array of 7-element array of highp float) 0:52 'a' ( in 5-element array of 7-element array of highp float)
0:52 Constant: 0:52 Constant:
......
...@@ -31,7 +31,7 @@ ERROR: node is still EOpNull! ...@@ -31,7 +31,7 @@ ERROR: node is still EOpNull!
0:9 'a' ( in 5-element array of mediump float) 0:9 'a' ( in 5-element array of mediump float)
0:11 Sequence 0:11 Sequence
0:11 Branch: Return with expression 0:11 Branch: Return with expression
0:11 Construct float ( temp 4-element array of float) 0:11 Construct float ( temp 4-element array of mediump float)
0:11 direct index ( temp mediump float) 0:11 direct index ( temp mediump float)
0:11 'a' ( in 5-element array of mediump float) 0:11 'a' ( in 5-element array of mediump float)
0:11 Constant: 0:11 Constant:
...@@ -168,7 +168,7 @@ ERROR: node is still EOpNull! ...@@ -168,7 +168,7 @@ ERROR: node is still EOpNull!
0:9 'a' ( in 5-element array of mediump float) 0:9 'a' ( in 5-element array of mediump float)
0:11 Sequence 0:11 Sequence
0:11 Branch: Return with expression 0:11 Branch: Return with expression
0:11 Construct float ( temp 4-element array of float) 0:11 Construct float ( temp 4-element array of mediump float)
0:11 direct index ( temp mediump float) 0:11 direct index ( temp mediump float)
0:11 'a' ( in 5-element array of mediump float) 0:11 'a' ( in 5-element array of mediump float)
0:11 Constant: 0:11 Constant:
......
spv.forwardFun.frag spv.forwardFun.frag
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 8000a // Generated by (magic number): 8000a
// Id's are bound by 64 // Id's are bound by 60
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 20 30 36 63 EntryPoint Fragment 4 "main" 20 30 36 59
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
Source GLSL 140 Source GLSL 140
Name 4 "main" Name 4 "main"
...@@ -20,7 +20,7 @@ spv.forwardFun.frag ...@@ -20,7 +20,7 @@ spv.forwardFun.frag
Name 27 "f" Name 27 "f"
Name 30 "gl_FragColor" Name 30 "gl_FragColor"
Name 36 "d" Name 36 "d"
Name 63 "bigColor" Name 59 "bigColor"
Decorate 10(unreachableReturn() RelaxedPrecision Decorate 10(unreachableReturn() RelaxedPrecision
Decorate 16(foo(vf4;) RelaxedPrecision Decorate 16(foo(vf4;) RelaxedPrecision
Decorate 15(bar) RelaxedPrecision Decorate 15(bar) RelaxedPrecision
...@@ -41,15 +41,11 @@ spv.forwardFun.frag ...@@ -41,15 +41,11 @@ spv.forwardFun.frag
Decorate 36(d) RelaxedPrecision Decorate 36(d) RelaxedPrecision
Decorate 36(d) Location 2 Decorate 36(d) Location 2
Decorate 37 RelaxedPrecision Decorate 37 RelaxedPrecision
Decorate 44 RelaxedPrecision Decorate 52 RelaxedPrecision
Decorate 45 RelaxedPrecision Decorate 55 RelaxedPrecision
Decorate 49 RelaxedPrecision
Decorate 50 RelaxedPrecision
Decorate 56 RelaxedPrecision Decorate 56 RelaxedPrecision
Decorate 59 RelaxedPrecision Decorate 59(bigColor) RelaxedPrecision
Decorate 60 RelaxedPrecision Decorate 59(bigColor) Location 0
Decorate 63(bigColor) RelaxedPrecision
Decorate 63(bigColor) Location 0
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
8: TypeFloat 32 8: TypeFloat 32
...@@ -67,11 +63,11 @@ spv.forwardFun.frag ...@@ -67,11 +63,11 @@ spv.forwardFun.frag
38: 8(float) Constant 1082549862 38: 8(float) Constant 1082549862
39: TypeBool 39: TypeBool
43: 8(float) Constant 1067030938 43: 8(float) Constant 1067030938
48: 8(float) Constant 1083179008 46: 8(float) Constant 1083179008
53: TypeInt 32 0 49: TypeInt 32 0
54: 53(int) Constant 0 50: 49(int) Constant 0
57: 53(int) Constant 1 53: 49(int) Constant 1
63(bigColor): 19(ptr) Variable Input 59(bigColor): 19(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
18(color): 13(ptr) Variable Function 18(color): 13(ptr) Variable Function
...@@ -97,31 +93,25 @@ spv.forwardFun.frag ...@@ -97,31 +93,25 @@ spv.forwardFun.frag
FunctionEnd FunctionEnd
10(unreachableReturn(): 8(float) Function None 9 10(unreachableReturn(): 8(float) Function None 9
11: Label 11: Label
44: 26(ptr) Variable Function
49: 26(ptr) Variable Function
34: 2 FunctionCall 6(bar() 34: 2 FunctionCall 6(bar()
37: 8(float) Load 36(d) 37: 8(float) Load 36(d)
40: 39(bool) FOrdLessThan 37 38 40: 39(bool) FOrdLessThan 37 38
SelectionMerge 42 None SelectionMerge 42 None
BranchConditional 40 41 47 BranchConditional 40 41 45
41: Label 41: Label
Store 44 43 ReturnValue 43
45: 8(float) Load 44 45: Label
ReturnValue 45 ReturnValue 46
47: Label
Store 49 48
50: 8(float) Load 49
ReturnValue 50
42: Label 42: Label
Unreachable Unreachable
FunctionEnd FunctionEnd
16(foo(vf4;): 8(float) Function None 14 16(foo(vf4;): 8(float) Function None 14
15(bar): 13(ptr) FunctionParameter 15(bar): 13(ptr) FunctionParameter
17: Label 17: Label
55: 26(ptr) AccessChain 15(bar) 54 51: 26(ptr) AccessChain 15(bar) 50
56: 8(float) Load 55 52: 8(float) Load 51
58: 26(ptr) AccessChain 15(bar) 57 54: 26(ptr) AccessChain 15(bar) 53
59: 8(float) Load 58 55: 8(float) Load 54
60: 8(float) FAdd 56 59 56: 8(float) FAdd 52 55
ReturnValue 60 ReturnValue 56
FunctionEnd FunctionEnd
...@@ -1231,6 +1231,7 @@ public: ...@@ -1231,6 +1231,7 @@ public:
TOperator getFlowOp() const { return flowOp; } TOperator getFlowOp() const { return flowOp; }
TIntermTyped* getExpression() const { return expression; } TIntermTyped* getExpression() const { return expression; }
void setExpression(TIntermTyped* pExpression) { expression = pExpression; } void setExpression(TIntermTyped* pExpression) { expression = pExpression; }
void updatePrecision(TPrecisionQualifier parentPrecision);
protected: protected:
TOperator flowOp; TOperator flowOp;
TIntermTyped* expression; TIntermTyped* expression;
......
...@@ -2777,6 +2777,22 @@ TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expres ...@@ -2777,6 +2777,22 @@ TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expres
return node; 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 // This is to be executed after the final root is put on top by the parsing
// process. // process.
...@@ -3284,9 +3300,11 @@ bool TIntermediate::promoteUnary(TIntermUnary& node) ...@@ -3284,9 +3300,11 @@ bool TIntermediate::promoteUnary(TIntermUnary& node)
return true; return true;
} }
// Propagate precision qualifiers *up* from children to parent.
void TIntermUnary::updatePrecision() 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) if (operand->getQualifier().precision > getQualifier().precision)
getQualifier().precision = operand->getQualifier().precision; getQualifier().precision = operand->getQualifier().precision;
} }
...@@ -3782,9 +3800,12 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node) ...@@ -3782,9 +3800,12 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
return false; return false;
} }
// Propagate precision qualifiers *up* from children to parent, and then
// back *down* again to the children's subtrees.
void TIntermBinary::updatePrecision() 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); getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
if (getQualifier().precision != EpqNone) { if (getQualifier().precision != EpqNone) {
left->propagatePrecision(getQualifier().precision); left->propagatePrecision(getQualifier().precision);
...@@ -3793,9 +3814,14 @@ void TIntermBinary::updatePrecision() ...@@ -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) 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; return;
getQualifier().precision = newPrecision; getQualifier().precision = newPrecision;
......
...@@ -1415,23 +1415,28 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType ...@@ -1415,23 +1415,28 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType
#endif #endif
functionReturnsValue = true; functionReturnsValue = true;
TIntermBranch* branch = nullptr;
if (currentFunctionType->getBasicType() == EbtVoid) { if (currentFunctionType->getBasicType() == EbtVoid) {
error(loc, "void function cannot return a value", "return", ""); error(loc, "void function cannot return a value", "return", "");
return intermediate.addBranch(EOpReturn, loc); branch = intermediate.addBranch(EOpReturn, loc);
} else if (*currentFunctionType != value->getType()) { } else if (*currentFunctionType != value->getType()) {
TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value); TIntermTyped* converted = intermediate.addConversion(EOpReturn, *currentFunctionType, value);
if (converted) { if (converted) {
if (*currentFunctionType != converted->getType()) if (*currentFunctionType != converted->getType())
error(loc, "cannot convert return value to function return type", "return", ""); error(loc, "cannot convert return value to function return type", "return", "");
if (version < 420) if (version < 420)
warn(loc, "type conversion on return values was not explicitly allowed until version 420", "return", ""); warn(loc, "type conversion on return values was not explicitly allowed until version 420",
return intermediate.addBranch(EOpReturn, converted, loc); "return", "");
branch = intermediate.addBranch(EOpReturn, converted, loc);
} else { } else {
error(loc, "type does not match, or is not convertible to, the function's return type", "return", ""); error(loc, "type does not match, or is not convertible to, the function's return type", "return", "");
return intermediate.addBranch(EOpReturn, value, loc); branch = intermediate.addBranch(EOpReturn, value, loc);
} }
} else } else
return intermediate.addBranch(EOpReturn, value, loc); branch = intermediate.addBranch(EOpReturn, value, loc);
branch->updatePrecision(currentFunctionType->getQualifier().precision);
return branch;
} }
// See if the operation is being done in an illegal location. // See if the operation is being done in an illegal location.
......
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