Add constant folding for the exp*(), log*(), *sqrt(), round*(), floor(), fract()...
authorJohn Kessenich <cepheus@frii.com>
Tue, 11 Jun 2013 00:09:48 +0000 (00:09 +0000)
committerJohn Kessenich <cepheus@frii.com>
Tue, 11 Jun 2013 00:09:48 +0000 (00:09 +0000)
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
glslang/MachineIndependent/Constant.cpp

index e08dc846a4ed2a857cfd4140ae23cd22875da59c..302113398eb9ac8ec4ba36b80860d6d5663f83df 100644 (file)
@@ -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
 }
index f635586cfdb4f1e55ddcd2ef1d213ad3a1214b77..152a581ea9c9cc000b68944f8bb1632de24fac0d 100644 (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: