Constant fold float pack/unpack functions
This change adds constant folding support for following floating
point pack and unpack functions:
- packSnorm2x16, unpackSnorm2x16, packUnorm2x16, unpackUnorm2x16,
packHalf2x16, and unpackHalf2x16.
BUG=angleproject:913
TEST=angle_unittests(new: MathUtilTest.packAndUnpack*), dEQP Tests
dEQP-GLES3.functional.shaders.constant_expressions.builtin_functions.float_pack_unpack.*
(all 10 tests started passing with this change)
Change-Id: I2b69faebee4127e5e13900b3a9485b7145950277
Reviewed-on: https://chromium-review.googlesource.com/282683
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index a83870a..4a84b24 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -1188,7 +1188,8 @@
size_t objectSize = getType().getObjectSize();
if (op == EOpAny || op == EOpAll || op == EOpLength || op == EOpTranspose || op == EOpDeterminant ||
- op == EOpInverse)
+ op == EOpInverse || op == EOpPackSnorm2x16 || op == EOpUnpackSnorm2x16 || op == EOpPackUnorm2x16 ||
+ op == EOpUnpackUnorm2x16 || op == EOpPackHalf2x16 || op == EOpUnpackHalf2x16)
{
// Do operations where the return type has a different number of components compared to the operand type.
TConstantUnion *resultArray = nullptr;
@@ -1296,6 +1297,97 @@
return nullptr;
}
+ case EOpPackSnorm2x16:
+ if (getType().getBasicType() == EbtFloat)
+ {
+ ASSERT(getType().getNominalSize() == 2);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
+
+ case EOpUnpackSnorm2x16:
+ if (getType().getBasicType() == EbtUInt)
+ {
+ resultArray = new TConstantUnion[2];
+ float f1, f2;
+ gl::unpackSnorm2x16(operandArray[0].getUConst(), &f1, &f2);
+ resultArray[0].setFConst(f1);
+ resultArray[1].setFConst(f2);
+ break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
+
+ case EOpPackUnorm2x16:
+ if (getType().getBasicType() == EbtFloat)
+ {
+ ASSERT(getType().getNominalSize() == 2);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
+
+ case EOpUnpackUnorm2x16:
+ if (getType().getBasicType() == EbtUInt)
+ {
+ resultArray = new TConstantUnion[2];
+ float f1, f2;
+ gl::unpackUnorm2x16(operandArray[0].getUConst(), &f1, &f2);
+ resultArray[0].setFConst(f1);
+ resultArray[1].setFConst(f2);
+ break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
+
+ case EOpPackHalf2x16:
+ if (getType().getBasicType() == EbtFloat)
+ {
+ ASSERT(getType().getNominalSize() == 2);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
+
+ case EOpUnpackHalf2x16:
+ if (getType().getBasicType() == EbtUInt)
+ {
+ resultArray = new TConstantUnion[2];
+ float f1, f2;
+ gl::unpackHalf2x16(operandArray[0].getUConst(), &f1, &f2);
+ resultArray[0].setFConst(f1);
+ resultArray[1].setFConst(f2);
+ break;
+ }
+ else
+ {
+ infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
+ return nullptr;
+ }
+ break;
+
default:
break;
}