Support constant folding of common built-ins

This change adds constant folding support for unary common built-ins:
abs, sign, floor, trunc, round, roundEven, ceil and fract.

BUG=angleproject:913
TEST= dEQP tests
dEQP-GLES3.functional.shaders.constant_expressions.builtin_functions.common*
(80 out of 210 tests started passing with this change)

Change-Id: I06800ed0e03764c0f7aab6bcd45c4f122de5a3c1
Reviewed-on: https://chromium-review.googlesource.com/265394
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
This commit is contained in:
Arun Patole 2015-04-06 17:35:38 +05:30 коммит произвёл Olli Etuaho
Родитель 62e2c8d2bc
Коммит 2b1da6ed1d
1 изменённых файлов: 100 добавлений и 0 удалений

Просмотреть файл

@ -1330,6 +1330,106 @@ TIntermTyped *TIntermConstantUnion::fold(
tempConstArray[i].setFConst(1.0f / tempConstArray[i].getFConst());
break;
case EOpAbs:
switch (getType().getBasicType())
{
case EbtFloat:
tempConstArray[i].setFConst(std::abs(unionArray[i].getFConst()));
break;
case EbtInt:
tempConstArray[i].setIConst(std::abs(unionArray[i].getIConst()));
break;
default:
infoSink.info.message(
EPrefixInternalError, getLine(),
"Unary operation not folded into constant");
return nullptr;
}
break;
case EOpSign:
switch (getType().getBasicType())
{
case EbtFloat:
{
float fConst = unionArray[i].getFConst();
float fResult = 0.0f;
if (fConst > 0.0f)
fResult = 1.0f;
else if (fConst < 0.0f)
fResult = -1.0f;
tempConstArray[i].setFConst(fResult);
}
break;
case EbtInt:
{
int iConst = unionArray[i].getIConst();
int iResult = 0;
if (iConst > 0)
iResult = 1;
else if (iConst < 0)
iResult = -1;
tempConstArray[i].setIConst(iResult);
}
break;
default:
infoSink.info.message(
EPrefixInternalError, getLine(),
"Unary operation not folded into constant");
return nullptr;
}
break;
case EOpFloor:
if (!foldFloatTypeUnary(unionArray[i], static_cast<FloatTypeUnaryFunc>(&std::floor), infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpTrunc:
if (!foldFloatTypeUnary(unionArray[i], static_cast<FloatTypeUnaryFunc>(&std::trunc), infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpRound:
if (!foldFloatTypeUnary(unionArray[i], static_cast<FloatTypeUnaryFunc>(&std::round), infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpRoundEven:
if (getType().getBasicType() == EbtFloat)
{
float x = unionArray[i].getFConst();
float result;
float fractPart = std::modf(x, &result);
if (std::abs(fractPart) == 0.5f)
result = 2.0f * std::round(x / 2.0f);
else
result = std::round(x);
tempConstArray[i].setFConst(result);
break;
}
infoSink.info.message(
EPrefixInternalError, getLine(),
"Unary operation not folded into constant");
return nullptr;
case EOpCeil:
if (!foldFloatTypeUnary(unionArray[i], static_cast<FloatTypeUnaryFunc>(&std::ceil), infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpFract:
if (getType().getBasicType() == EbtFloat)
{
float x = unionArray[i].getFConst();
tempConstArray[i].setFConst(x - std::floor(x));
break;
}
infoSink.info.message(
EPrefixInternalError, getLine(),
"Unary operation not folded into constant");
return nullptr;
default:
return NULL;
}