From ad3663be1fba9be10e41bd2c9f77b67ef6050c75 Mon Sep 17 00:00:00 2001
From: John Kessenich <cepheus@frii.com>
Date: Sun, 7 Apr 2013 20:04:12 +0000
Subject: [PATCH] Add ES 300 built-ins trunc, round, roundEven, modf, isnan,
 isinf, floatBitsToInt, floatBitsToUint, intBitsToFloat, uintBitsToFloat,
 packSnorm2x16, unpackSnorm2x16, packUnorm2x16, unpackUnorm2x16, packHalf2x16,
 and unpackHalf2x16, and new form of min, max, clamp, and mix.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21063 e7fa87d3-cd2b-0410-9028-fcbf551c1848
---
 Test/300BuiltIns.frag                     |  68 +++++++++
 Test/precision.frag                       |   5 +
 Test/testlist                             |   1 +
 glslang/Include/intermediate.h            |  18 +++
 glslang/MachineIndependent/Constant.cpp   |  20 ++-
 glslang/MachineIndependent/Initialize.cpp | 163 ++++++++++++++++++++++
 glslang/MachineIndependent/intermOut.cpp  |  18 +++
 7 files changed, 292 insertions(+), 1 deletion(-)
 create mode 100644 Test/300BuiltIns.frag

diff --git a/Test/300BuiltIns.frag b/Test/300BuiltIns.frag
new file mode 100644
index 000000000..0c0844434
--- /dev/null
+++ b/Test/300BuiltIns.frag
@@ -0,0 +1,68 @@
+#version 300 es
+
+int imax, imin;
+uint umax, umin;
+
+vec3 x, y;
+bvec3 bv;
+
+uint uy;
+uvec2 uv2c;
+uvec2 uv2y;
+uvec2 uv2x;
+uvec4 uv4y;
+
+ivec3 iv3a;
+ivec3 iv3b;
+
+ivec4 iv4a;
+ivec4 iv4b;
+
+float f;
+
+vec2 v2a, v2b;
+vec4 v4;
+
+void main()
+{
+    // 1.3 int
+    vec3 v = mix(x, y, bv);
+    ivec4 iv10 = abs(iv4a);
+    ivec4 iv11 = sign(iv4a);
+    ivec4 iv12 = min(iv4a, iv4b);
+    ivec4 iv13 = min(iv4a, imin);
+    uvec2 u = min(uv2x, uv2y);
+    uvec4 uv = min(uv4y, uy);
+    ivec3 iv14 = max(iv3a, iv3b);
+    ivec4 iv15 = max(iv4a, imax);
+    uvec2 u10 = max(uv2x, uv2y);
+    uvec2 u11 = max(uv2x, uy);
+    ivec4 iv16 = clamp(iv4a, iv4a, iv4b);
+    ivec4 iv17 = clamp(iv4a, imin, imax);
+    uvec2 u12 = clamp(uv2x, uv2y, uv2c);
+    uvec4 uv10 = clamp(uv4y, umin, umax);
+
+    // 1.3 float
+    vec3 modfOut;
+    vec3 v11 = modf(x, modfOut);
+
+    float t = trunc(f);
+    vec2 v12 = round(v2a);
+    vec2 v13 = roundEven(v2a);
+    bvec2 b10 = isnan(v2a);
+    bvec4 b11 = isinf(v4);
+
+    // 3.3 float
+    int i = floatBitsToInt(f);
+    uvec4 uv11 = floatBitsToUint(v4);
+    vec4 v14 = intBitsToFloat(iv4a);
+    vec2 v15 = uintBitsToFloat(uv2c);
+
+    // 4.0  pack
+    uint u19 = packSnorm2x16(v2a);
+    vec2 v20 = unpackSnorm2x16(uy);
+    uint u15 = packUnorm2x16(v2a);
+    vec2 v16 = unpackUnorm2x16(uy);
+    uint u17 = packHalf2x16(v2b);
+    vec2 v18 = unpackHalf2x16(uy);
+}
diff --git a/Test/precision.frag b/Test/precision.frag
index c4339ae0a..7fe5af9f9 100644
--- a/Test/precision.frag
+++ b/Test/precision.frag
@@ -30,6 +30,11 @@ void main()
     precision lowp int;
     int level1_low;
     sum += level1_low;
+    
+    // test maxing precisions of args to get precision of builtin
+    lowp float arg1;
+    mediump float arg2;
+    lowp float d = distance(arg1, arg2);
 
     {
         int level2_low;
diff --git a/Test/testlist b/Test/testlist
index b01e2fc20..7ae5e7bd4 100644
--- a/Test/testlist
+++ b/Test/testlist
@@ -23,6 +23,7 @@ array100.frag
 comment.frag
 300.vert
 300.frag
+300BuiltIns.frag
 330.frag
 330comp.frag
 constErrors.frag
diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h
index e8de09a79..69229ce91 100644
--- a/glslang/Include/intermediate.h
+++ b/glslang/Include/intermediate.h
@@ -160,8 +160,12 @@ enum TOperator {
     EOpAbs,
     EOpSign,
     EOpFloor,
+    EOpTrunc,
+    EOpRound,
+    EOpRoundEven,
     EOpCeil,
     EOpFract,
+    EOpModf,
     EOpMin,
     EOpMax,
     EOpClamp,
@@ -169,6 +173,20 @@ enum TOperator {
     EOpStep,
     EOpSmoothStep,
 
+    EOpIsNan,
+    EOpIsInf,
+
+    EOpFloatBitsToInt,
+    EOpFloatBitsToUint,
+    EOpIntBitsToFloat,
+    EOpUintBitsToFloat,
+    EOpPackSnorm2x16,
+    EOpUnpackSnorm2x16,
+    EOpPackUnorm2x16,
+    EOpUnpackUnorm2x16,
+    EOpPackHalf2x16,
+    EOpUnpackHalf2x16,
+
     EOpLength,
     EOpDistance,
     EOpDot,
diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp
index 0b1c99112..27130d82b 100644
--- a/glslang/MachineIndependent/Constant.cpp
+++ b/glslang/MachineIndependent/Constant.cpp
@@ -444,10 +444,27 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType,
 
         case EOpAbs:
         case EOpSign:
-        case EOpFloor:
+        case EOpFloor:            
+        case EOpTrunc:
+        case EOpRound:
+        case EOpRoundEven:
         case EOpCeil:
         case EOpFract:
 
+        case EOpIsNan:
+        case EOpIsInf:
+
+        case EOpFloatBitsToInt:
+        case EOpFloatBitsToUint:
+        case EOpIntBitsToFloat:
+        case EOpUintBitsToFloat:
+        case EOpPackSnorm2x16:
+        case EOpUnpackSnorm2x16:
+        case EOpPackUnorm2x16:
+        case EOpUnpackUnorm2x16:
+        case EOpPackHalf2x16:
+        case EOpUnpackHalf2x16:
+
         case EOpLength:
 
         case EOpDPdx:
@@ -549,6 +566,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
 
     case EOpAtan:
     case EOpPow:
+    case EOpModf:
     case EOpClamp:
     case EOpMix:
     case EOpStep:
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index dad01c959..e5c77378c 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -186,16 +186,48 @@ void TBuiltIns::initialize(int version, EProfile profile)
         s.append(TString("vec3  abs(vec3  x);"));
         s.append(TString("vec4  abs(vec4  x);"));
 
+        if (version >= 130) {
+            s.append(TString("  int abs(  int x);"));
+            s.append(TString("ivec2 abs(ivec2 x);"));
+            s.append(TString("ivec3 abs(ivec3 x);"));
+            s.append(TString("ivec4 abs(ivec4 x);"));
+        }
+
+
         s.append(TString("float sign(float x);"));
         s.append(TString("vec2  sign(vec2  x);"));
         s.append(TString("vec3  sign(vec3  x);"));
         s.append(TString("vec4  sign(vec4  x);"));
 
+        if (version >= 130) {
+            s.append(TString("  int sign(  int x);"));
+            s.append(TString("ivec2 sign(ivec2 x);"));
+            s.append(TString("ivec3 sign(ivec3 x);"));
+            s.append(TString("ivec4 sign(ivec4 x);"));
+        }
+
         s.append(TString("float floor(float x);"));
         s.append(TString("vec2  floor(vec2  x);"));
         s.append(TString("vec3  floor(vec3  x);"));
         s.append(TString("vec4  floor(vec4  x);"));
 
+        if (version >= 130) {
+            s.append(TString("float trunc(float x);"));
+            s.append(TString("vec2  trunc(vec2  x);"));
+            s.append(TString("vec3  trunc(vec3  x);"));
+            s.append(TString("vec4  trunc(vec4  x);"));
+
+            s.append(TString("float round(float x);"));
+            s.append(TString("vec2  round(vec2  x);"));
+            s.append(TString("vec3  round(vec3  x);"));
+            s.append(TString("vec4  round(vec4  x);"));
+
+            s.append(TString("float roundEven(float x);"));
+            s.append(TString("vec2  roundEven(vec2  x);"));
+            s.append(TString("vec3  roundEven(vec3  x);"));
+            s.append(TString("vec4  roundEven(vec4  x);"));
+        }
+
         s.append(TString("float ceil(float x);"));
         s.append(TString("vec2  ceil(vec2  x);"));
         s.append(TString("vec3  ceil(vec3  x);"));
@@ -214,6 +246,13 @@ void TBuiltIns::initialize(int version, EProfile profile)
         s.append(TString("vec3  mod(vec3  x, vec3  y);"));
         s.append(TString("vec4  mod(vec4  x, vec4  y);"));
 
+        if (version >= 130) {
+            s.append(TString("float modf(float, out float);"));
+            s.append(TString("vec2  modf(vec2,  out vec2 );"));
+            s.append(TString("vec3  modf(vec3,  out vec3 );"));
+            s.append(TString("vec4  modf(vec4,  out vec4 );"));
+        }
+
         s.append(TString("float min(float x, float y);"));
         s.append(TString("vec2  min(vec2  x, float y);"));
         s.append(TString("vec3  min(vec3  x, float y);"));
@@ -222,6 +261,24 @@ void TBuiltIns::initialize(int version, EProfile profile)
         s.append(TString("vec3  min(vec3  x, vec3  y);"));
         s.append(TString("vec4  min(vec4  x, vec4  y);"));
 
+        if (version >= 130) {
+            s.append(TString("  int min(int    x, int y);"));
+            s.append(TString("ivec2 min(ivec2  x, int y);"));
+            s.append(TString("ivec3 min(ivec3  x, int y);"));
+            s.append(TString("ivec4 min(ivec4  x, int y);"));
+            s.append(TString("ivec2 min(ivec2  x, ivec2  y);"));
+            s.append(TString("ivec3 min(ivec3  x, ivec3  y);"));
+            s.append(TString("ivec4 min(ivec4  x, ivec4  y);"));
+
+            s.append(TString(" uint min(uint   x, uint y);"));
+            s.append(TString("uvec2 min(uvec2  x, uint y);"));
+            s.append(TString("uvec3 min(uvec3  x, uint y);"));
+            s.append(TString("uvec4 min(uvec4  x, uint y);"));
+            s.append(TString("uvec2 min(uvec2  x, uvec2  y);"));
+            s.append(TString("uvec3 min(uvec3  x, uvec3  y);"));
+            s.append(TString("uvec4 min(uvec4  x, uvec4  y);"));
+        }
+
         s.append(TString("float max(float x, float y);"));
         s.append(TString("vec2  max(vec2  x, float y);"));
         s.append(TString("vec3  max(vec3  x, float y);"));
@@ -230,6 +287,24 @@ void TBuiltIns::initialize(int version, EProfile profile)
         s.append(TString("vec3  max(vec3  x, vec3  y);"));
         s.append(TString("vec4  max(vec4  x, vec4  y);"));
 
+        if (version >= 130) {
+            s.append(TString("  int max(int    x, int y);"));
+            s.append(TString("ivec2 max(ivec2  x, int y);"));
+            s.append(TString("ivec3 max(ivec3  x, int y);"));
+            s.append(TString("ivec4 max(ivec4  x, int y);"));
+            s.append(TString("ivec2 max(ivec2  x, ivec2  y);"));
+            s.append(TString("ivec3 max(ivec3  x, ivec3  y);"));
+            s.append(TString("ivec4 max(ivec4  x, ivec4  y);"));
+
+            s.append(TString(" uint max(uint   x, uint y);"));
+            s.append(TString("uvec2 max(uvec2  x, uint y);"));
+            s.append(TString("uvec3 max(uvec3  x, uint y);"));
+            s.append(TString("uvec4 max(uvec4  x, uint y);"));
+            s.append(TString("uvec2 max(uvec2  x, uvec2  y);"));
+            s.append(TString("uvec3 max(uvec3  x, uvec3  y);"));
+            s.append(TString("uvec4 max(uvec4  x, uvec4  y);"));
+        }
+
         s.append(TString("float clamp(float x, float minVal, float maxVal);"));
         s.append(TString("vec2  clamp(vec2  x, float minVal, float maxVal);"));
         s.append(TString("vec3  clamp(vec3  x, float minVal, float maxVal);"));
@@ -238,6 +313,24 @@ void TBuiltIns::initialize(int version, EProfile profile)
         s.append(TString("vec3  clamp(vec3  x, vec3  minVal, vec3  maxVal);"));
         s.append(TString("vec4  clamp(vec4  x, vec4  minVal, vec4  maxVal);"));
 
+        if (version >= 130) {
+            s.append(TString("int    clamp(int x, int minVal, int maxVal);"));
+            s.append(TString("ivec2  clamp(ivec2  x, int minVal, int maxVal);"));
+            s.append(TString("ivec3  clamp(ivec3  x, int minVal, int maxVal);"));
+            s.append(TString("ivec4  clamp(ivec4  x, int minVal, int maxVal);"));
+            s.append(TString("ivec2  clamp(ivec2  x, ivec2  minVal, ivec2  maxVal);"));
+            s.append(TString("ivec3  clamp(ivec3  x, ivec3  minVal, ivec3  maxVal);"));
+            s.append(TString("ivec4  clamp(ivec4  x, ivec4  minVal, ivec4  maxVal);"));
+
+            s.append(TString("uint   clamp(uint x, uint minVal, uint maxVal);"));
+            s.append(TString("uvec2  clamp(uvec2  x, uint minVal, uint maxVal);"));
+            s.append(TString("uvec3  clamp(uvec3  x, uint minVal, uint maxVal);"));
+            s.append(TString("uvec4  clamp(uvec4  x, uint minVal, uint maxVal);"));
+            s.append(TString("uvec2  clamp(uvec2  x, uvec2  minVal, uvec2  maxVal);"));
+            s.append(TString("uvec3  clamp(uvec3  x, uvec3  minVal, uvec3  maxVal);"));
+            s.append(TString("uvec4  clamp(uvec4  x, uvec4  minVal, uvec4  maxVal);"));
+        }
+
         s.append(TString("float mix(float x, float y, float a);"));
         s.append(TString("vec2  mix(vec2  x, vec2  y, float a);"));
         s.append(TString("vec3  mix(vec3  x, vec3  y, float a);"));
@@ -246,6 +339,13 @@ void TBuiltIns::initialize(int version, EProfile profile)
         s.append(TString("vec3  mix(vec3  x, vec3  y, vec3  a);"));
         s.append(TString("vec4  mix(vec4  x, vec4  y, vec4  a);"));
 
+        if (version >= 130) {
+            s.append(TString("float mix(float x, float y, bool  a);"));
+            s.append(TString("vec2  mix(vec2  x, vec2  y, bvec2 a);"));
+            s.append(TString("vec3  mix(vec3  x, vec3  y, bvec3 a);"));
+            s.append(TString("vec4  mix(vec4  x, vec4  y, bvec4 a);"));
+        }
+
         s.append(TString("float step(float edge, float x);"));
         s.append(TString("vec2  step(vec2  edge, vec2  x);"));
         s.append(TString("vec3  step(vec3  edge, vec3  x);"));
@@ -262,6 +362,51 @@ void TBuiltIns::initialize(int version, EProfile profile)
         s.append(TString("vec3  smoothstep(float edge0, float edge1, vec3  x);"));
         s.append(TString("vec4  smoothstep(float edge0, float edge1, vec4  x);"));
 
+        if (version >= 130) {
+            s.append(TString("bool  isnan(float x);"));
+            s.append(TString("bvec2 isnan(vec2  x);"));
+            s.append(TString("bvec3 isnan(vec3  x);"));
+            s.append(TString("bvec4 isnan(vec4  x);"));
+
+            s.append(TString("bool  isinf(float x);"));
+            s.append(TString("bvec2 isinf(vec2  x);"));
+            s.append(TString("bvec3 isinf(vec3  x);"));
+            s.append(TString("bvec4 isinf(vec4  x);"));
+        }
+
+        if (profile == EEsProfile && version >= 300 ||
+            profile != EEsProfile && version >= 330) {
+            s.append(TString("int   floatBitsToInt(float value);"));
+            s.append(TString("ivec2 floatBitsToInt(vec2  value);"));
+            s.append(TString("ivec3 floatBitsToInt(vec3  value);"));
+            s.append(TString("ivec4 floatBitsToInt(vec4  value);"));
+
+            s.append(TString("uint  floatBitsToUint(float value);"));
+            s.append(TString("uvec2 floatBitsToUint(vec2  value);"));
+            s.append(TString("uvec3 floatBitsToUint(vec3  value);"));
+            s.append(TString("uvec4 floatBitsToUint(vec4  value);"));
+
+            s.append(TString("float intBitsToFloat(int   value);"));
+            s.append(TString("vec2  intBitsToFloat(ivec2 value);"));
+            s.append(TString("vec3  intBitsToFloat(ivec3 value);"));
+            s.append(TString("vec4  intBitsToFloat(ivec4 value);"));
+
+            s.append(TString("float uintBitsToFloat(uint  value);"));
+            s.append(TString("vec2  uintBitsToFloat(uvec2 value);"));
+            s.append(TString("vec3  uintBitsToFloat(uvec3 value);"));
+            s.append(TString("vec4  uintBitsToFloat(uvec4 value);"));
+        }
+
+        if (profile == EEsProfile && version >= 300 ||
+            profile != EEsProfile && version >= 400) {
+            s.append(TString(  "highp uint packSnorm2x16 (vec2);"));
+            s.append(TString(  "highp vec2 unpackSnorm2x16 (highp uint);"));
+            s.append(TString(  "highp uint packUnorm2x16 (vec2);"));
+            s.append(TString(  "highp vec2 unpackUnorm2x16 (highp uint);"));
+            s.append(TString(  "highp uint packHalf2x16(mediump vec2);"));
+            s.append(TString("mediump vec2 unpackHalf2x16(highp uint);"));
+        }
+
         //
         // Geometric Functions.
         //
@@ -1343,6 +1488,7 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
     }
 
     symbolTable.relateToOperator("mod",              EOpMod);
+    symbolTable.relateToOperator("modf",             EOpModf);
 
     symbolTable.relateToOperator("equal",            EOpVectorEqual);
     symbolTable.relateToOperator("notEqual",         EOpVectorNotEqual);
@@ -1371,6 +1517,9 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
     symbolTable.relateToOperator("abs",          EOpAbs);
     symbolTable.relateToOperator("sign",         EOpSign);
     symbolTable.relateToOperator("floor",        EOpFloor);
+    symbolTable.relateToOperator("trunc",        EOpTrunc);
+    symbolTable.relateToOperator("round",        EOpRound);
+    symbolTable.relateToOperator("roundEven",    EOpRoundEven);
     symbolTable.relateToOperator("ceil",         EOpCeil);
     symbolTable.relateToOperator("fract",        EOpFract);
     symbolTable.relateToOperator("min",          EOpMin);
@@ -1380,6 +1529,20 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
     symbolTable.relateToOperator("step",         EOpStep);
     symbolTable.relateToOperator("smoothstep",   EOpSmoothStep);
 
+    symbolTable.relateToOperator("isnan",  EOpIsNan);
+    symbolTable.relateToOperator("isinf",  EOpIsInf);
+
+    symbolTable.relateToOperator("floatBitsToInt",  EOpFloatBitsToInt);
+    symbolTable.relateToOperator("floatBitsToUint", EOpFloatBitsToUint);
+    symbolTable.relateToOperator("intBitsToFloat",  EOpIntBitsToFloat);
+    symbolTable.relateToOperator("uintBitsToFloat", EOpUintBitsToFloat);
+    symbolTable.relateToOperator("packSnorm2x16",   EOpPackSnorm2x16);
+    symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16);
+    symbolTable.relateToOperator("packUnorm2x16",   EOpPackUnorm2x16);
+    symbolTable.relateToOperator("unpackUnorm2x16", EOpUnpackUnorm2x16);
+    symbolTable.relateToOperator("packHalf2x16",    EOpPackHalf2x16);
+    symbolTable.relateToOperator("unpackHalf2x16",  EOpUnpackHalf2x16);
+
     symbolTable.relateToOperator("length",       EOpLength);
     symbolTable.relateToOperator("distance",     EOpDistance);
     symbolTable.relateToOperator("dot",          EOpDot);
diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp
index 9a769a1f9..982608463 100644
--- a/glslang/MachineIndependent/intermOut.cpp
+++ b/glslang/MachineIndependent/intermOut.cpp
@@ -216,9 +216,26 @@ bool OutputUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
     case EOpAbs:            out.debug << "Absolute value";       break;
     case EOpSign:           out.debug << "Sign";                 break;
     case EOpFloor:          out.debug << "Floor";                break;
+    case EOpTrunc:          out.debug << "trunc";                break;
+    case EOpRound:          out.debug << "round";                break;
+    case EOpRoundEven:      out.debug << "roundEven";            break;
     case EOpCeil:           out.debug << "Ceiling";              break;
     case EOpFract:          out.debug << "Fraction";             break;
 
+    case EOpIsNan:          out.debug << "isnan";                break;
+    case EOpIsInf:          out.debug << "isinf";                break;
+
+    case EOpFloatBitsToInt: out.debug << "floatBitsToInt";       break;
+    case EOpFloatBitsToUint:out.debug << "floatBitsToUint";      break;
+    case EOpIntBitsToFloat: out.debug << "intBitsToFloat";       break;
+    case EOpUintBitsToFloat:out.debug << "uintBitsToFloat";      break;
+    case EOpPackSnorm2x16:  out.debug << "packSnorm2x16";        break;
+    case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16";      break;
+    case EOpPackUnorm2x16:  out.debug << "packUnorm2x16";        break;
+    case EOpUnpackUnorm2x16:out.debug << "unpackUnorm2x16";      break;
+    case EOpPackHalf2x16:   out.debug << "packHalf2x16";         break;
+    case EOpUnpackHalf2x16: out.debug << "unpackHalf2x16";       break;
+
     case EOpLength:         out.debug << "length";               break;
     case EOpNormalize:      out.debug << "normalize";            break;
     case EOpDPdx:           out.debug << "dPdx";                 break;
@@ -304,6 +321,7 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
     case EOpVectorNotEqual:   out.debug << "NotEqual";                      break;
 
     case EOpMod:           out.debug << "mod";         break;
+    case EOpModf:          out.debug << "modf";        break;
     case EOpPow:           out.debug << "pow";         break;
 
     case EOpAtan:          out.debug << "arc tangent"; break;
-- 
GitLab