Add support for constant folding of clamp() Fixes: dEQP-GLES3.functional.shaders.constant_expressions.other.complex* Bug: b/116598062 Change-Id: Ife2dd2edad17d6ebbd02653f484637672ce6af0a Reviewed-on: https://swiftshader-review.googlesource.com/20828 Reviewed-by: Nicolas Capens <nicolascapens@google.com> Tested-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp index b795c06..bf731ea 100644 --- a/src/OpenGL/compiler/ParseHelper.cpp +++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -3629,24 +3629,48 @@ callNode = aggregate; - if(fnCandidate->getParamCount() == 2) + if(op == EOpClamp) { + // Special case for clamp -- try to fold it as min(max(t, minVal), maxVal) TIntermSequence ¶meters = paramNode->getAsAggregate()->getSequence(); - TIntermTyped *left = parameters[0]->getAsTyped(); - TIntermTyped *right = parameters[1]->getAsTyped(); + TIntermConstantUnion *valConstant = parameters[0]->getAsTyped()->getAsConstantUnion(); + TIntermConstantUnion *minConstant = parameters[1]->getAsTyped()->getAsConstantUnion(); + TIntermConstantUnion *maxConstant = parameters[2]->getAsTyped()->getAsConstantUnion(); - TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); - TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); - if (leftTempConstant && rightTempConstant) + if (valConstant && minConstant && maxConstant) { - TIntermTyped *typedReturnNode = leftTempConstant->fold(op, rightTempConstant, infoSink()); - - if(typedReturnNode) + TIntermTyped *typedReturnNode = valConstant->fold(EOpMax, minConstant, infoSink()); + if (typedReturnNode && typedReturnNode->getAsConstantUnion()) + { + typedReturnNode = maxConstant->fold(EOpMin, typedReturnNode->getAsConstantUnion(), infoSink()); + } + if (typedReturnNode) { callNode = typedReturnNode; } } } + else + { + if(fnCandidate->getParamCount() == 2) + { + TIntermSequence ¶meters = paramNode->getAsAggregate()->getSequence(); + TIntermTyped *left = parameters[0]->getAsTyped(); + TIntermTyped *right = parameters[1]->getAsTyped(); + + TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); + TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); + if (leftTempConstant && rightTempConstant) + { + TIntermTyped *typedReturnNode = leftTempConstant->fold(op, rightTempConstant, infoSink()); + + if(typedReturnNode) + { + callNode = typedReturnNode; + } + } + } + } } } else