From a5cecfc6b6f0bcc0a9b3f0794c39dbf0168ab65c Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Tue, 11 Jun 2013 00:09:48 +0000 Subject: [PATCH] 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 --- Test/constFold.frag | 16 ++++++++- glslang/MachineIndependent/Constant.cpp | 62 ++++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/Test/constFold.frag b/Test/constFold.frag index e08dc84..3021133 100644 --- a/Test/constFold.frag +++ b/Test/constFold.frag @@ -13,7 +13,14 @@ const vec2 pytho = vec2(3.0, 4.0); in vec4 inv; out vec4 FragColor; out vec2 out2; - +out vec4 out3; +out vec4 out4; +out ivec4 out5; +out vec3 out6; +out vec4 out7; +out vec4 out8; +out vec4 out9; + void main() { vec4 dx = dFdx(inv); @@ -30,4 +37,11 @@ void main() vec4 arrayMin[int(min(float(array2.length()), float(array3.length())))]; FragColor = vec4(arrayMax.length(), arrayMin.length(), sin(3.14), cos(3.14)); // 3, 2, .00159, -.999 out2 = length(pytho) + normalize(pytho) + dFdx(pytho) + dFdy(pytho) + fwidth(pytho); // 5+3/5, 5+4/5 + out3 = vec4(exp(3.0), log(10.0), exp2(4.0), log2(256.0)); // 20.08, 2.3, 16, 8 + out4 = vec4(sqrt(100.0), inversesqrt(100.0), abs(-4.7), abs(10.9)); // 10, .1, 4.7, 10.9 + out5 = ivec4(abs(-8) + sign(0), abs(17), sign(-12), sign(9)); // 8, 17, -1, 1 + out6 = vec3(sign(-8.8), sign(18.0), sign(0.0)); // -1.0, 1.0, 0.0 + out7 = vec4(floor(4.2), ceil(-4.1), trunc(5.9), trunc(-5.9)); // 4, -4, 5, -5 + out8 = vec4(round(4.4), round(4.6), roundEven(4.5), roundEven(-5.5)); // 4, 5, 4, -6 + out9 = vec4(roundEven(7.5), roundEven(-4.5), fract(2.345), fract(-2.6)); // 8, -4, .345, 0.4 } diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index f635586..152a581 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -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: -- 2.7.4