зеркало из https://github.com/AvaloniaUI/angle.git
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:
Родитель
62e2c8d2bc
Коммит
2b1da6ed1d
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче