Add constant folding for the exp*(), log*(), *sqrt(), round*(), floor(), fract(), ceil(), abs(), and sign() built in functions.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21927 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-06-11 00:09:48 +00:00
parent fddf3ce3a1
commit a5cecfc6b6
2 changed files with 73 additions and 5 deletions

View file

@ -34,8 +34,8 @@
//POSSIBILITY OF SUCH DAMAGE.
//
//??#include "float.h"
#include "localintermediate.h"
#include "math.h"
namespace {
@ -467,23 +467,77 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
newConstArray[i].setDConst(0.0);
break;
// TODO: Functionality: constant folding: the rest of the ops have to be fleshed out
case EOpExp:
newConstArray[i].setDConst(exp(unionArray[i].getDConst()));
break;
case EOpLog:
newConstArray[i].setDConst(log(unionArray[i].getDConst()));
break;
case EOpExp2:
{
const double inv_log2_e = 0.69314718055994530941723212145818;
newConstArray[i].setDConst(exp(unionArray[i].getDConst() * inv_log2_e));
break;
}
case EOpLog2:
{
const double log2_e = 1.4426950408889634073599246810019;
newConstArray[i].setDConst(log2_e * log(unionArray[i].getDConst()));
break;
}
case EOpSqrt:
newConstArray[i].setDConst(sqrt(unionArray[i].getDConst()));
break;
case EOpInverseSqrt:
newConstArray[i].setDConst(1.0 / sqrt(unionArray[i].getDConst()));
break;
case EOpAbs:
if (unionArray[i].getType() == EbtDouble)
newConstArray[i].setDConst(abs(unionArray[i].getDConst()));
else if (unionArray[i].getType() == EbtInt)
newConstArray[i].setIConst(abs(unionArray[i].getIConst()));
else
newConstArray[i] = unionArray[i];
break;
case EOpSign:
case EOpFloor:
#define SIGN(X) (X == 0 ? 0 : (X < 0 ? -1 : 1))
if (unionArray[i].getType() == EbtDouble)
newConstArray[i].setDConst(SIGN(unionArray[i].getDConst()));
else
newConstArray[i].setIConst(SIGN(unionArray[i].getIConst()));
break;
case EOpFloor:
newConstArray[i].setDConst(floor(unionArray[i].getDConst()));
break;
case EOpTrunc:
if (unionArray[i].getDConst() > 0)
newConstArray[i].setDConst(floor(unionArray[i].getDConst()));
else
newConstArray[i].setDConst(ceil(unionArray[i].getDConst()));
break;
case EOpRound:
newConstArray[i].setDConst(floor(0.5 + unionArray[i].getDConst()));
break;
case EOpRoundEven:
{
double flr = floor(unionArray[i].getDConst());
bool even = flr / 2.0 == floor(flr / 2.0);
double rounded = even ? ceil(unionArray[i].getDConst() - 0.5) : floor(unionArray[i].getDConst() + 0.5);
newConstArray[i].setDConst(rounded);
break;
}
case EOpCeil:
newConstArray[i].setDConst(ceil(unionArray[i].getDConst()));
break;
case EOpFract:
{
double x = unionArray[i].getDConst();
newConstArray[i].setDConst(x - floor(x));
break;
}
// TODO: Functionality: constant folding: the rest of the ops have to be fleshed out
case EOpIsNan:
case EOpIsInf: