Add new ESSL 3.10 pack/unpack builtins

This adds new built-ins found in ESSL 3.10 section 8.4 Floating-Point
Pack and Unpack Functions.

This includes constant folding support and support for both GLSL and
HLSL output. In HLSL all of these functions need to be emulated.

BUG=angleproject:1730
TEST=angle_unittests
TEST=dEQP-GLES31.functional.shaders.*pack*norm4x8*

Change-Id: Ibed60286a366cd35c4faafd405e79af562a02a06
Reviewed-on: https://chromium-review.googlesource.com/434170
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/common/mathutil.h b/src/common/mathutil.h
index 1243d3d..436fd22 100644
--- a/src/common/mathutil.h
+++ b/src/common/mathutil.h
@@ -669,6 +669,86 @@
     *f2 = static_cast<float>(mostSignificantBits) / 65535.0f;
 }
 
+// Helper functions intended to be used only here.
+namespace priv
+{
+
+inline uint8_t ToPackedUnorm8(float f)
+{
+    return static_cast<uint8_t>(roundf(clamp(f, 0.0f, 1.0f) * 255.0f));
+}
+
+inline int8_t ToPackedSnorm8(float f)
+{
+    return static_cast<int8_t>(roundf(clamp(f, -1.0f, 1.0f) * 127.0f));
+}
+
+}  // namespace priv
+
+// Packs 4 normalized unsigned floating-point values to a single 32-bit unsigned integer. Works
+// similarly to packUnorm2x16. The floats are clamped to the range 0.0 to 1.0, and written to the
+// unsigned integer starting from the least significant bits.
+inline uint32_t PackUnorm4x8(float f1, float f2, float f3, float f4)
+{
+    uint8_t bits[4];
+    bits[0]         = priv::ToPackedUnorm8(f1);
+    bits[1]         = priv::ToPackedUnorm8(f2);
+    bits[2]         = priv::ToPackedUnorm8(f3);
+    bits[3]         = priv::ToPackedUnorm8(f4);
+    uint32_t result = 0u;
+    for (int i = 0; i < 4; ++i)
+    {
+        int shift = i * 8;
+        result |= (static_cast<uint32_t>(bits[i]) << shift);
+    }
+    return result;
+}
+
+// Unpacks 4 normalized unsigned floating-point values from a single 32-bit unsigned integer into f.
+// Works similarly to unpackUnorm2x16. The floats are unpacked starting from the least significant
+// bits.
+inline void UnpackUnorm4x8(uint32_t u, float *f)
+{
+    for (int i = 0; i < 4; ++i)
+    {
+        int shift    = i * 8;
+        uint8_t bits = static_cast<uint8_t>((u >> shift) & 0xFF);
+        f[i]         = static_cast<float>(bits) / 255.0f;
+    }
+}
+
+// Packs 4 normalized signed floating-point values to a single 32-bit unsigned integer. The floats
+// are clamped to the range -1.0 to 1.0, and written to the unsigned integer starting from the least
+// significant bits.
+inline uint32_t PackSnorm4x8(float f1, float f2, float f3, float f4)
+{
+    int8_t bits[4];
+    bits[0]         = priv::ToPackedSnorm8(f1);
+    bits[1]         = priv::ToPackedSnorm8(f2);
+    bits[2]         = priv::ToPackedSnorm8(f3);
+    bits[3]         = priv::ToPackedSnorm8(f4);
+    uint32_t result = 0u;
+    for (int i = 0; i < 4; ++i)
+    {
+        int shift = i * 8;
+        result |= ((static_cast<uint32_t>(bits[i]) & 0xFF) << shift);
+    }
+    return result;
+}
+
+// Unpacks 4 normalized signed floating-point values from a single 32-bit unsigned integer into f.
+// Works similarly to unpackSnorm2x16. The floats are unpacked starting from the least significant
+// bits, and clamped to the range -1.0 to 1.0.
+inline void UnpackSnorm4x8(uint32_t u, float *f)
+{
+    for (int i = 0; i < 4; ++i)
+    {
+        int shift   = i * 8;
+        int8_t bits = static_cast<int8_t>((u >> shift) & 0xFF);
+        f[i]        = clamp(static_cast<float>(bits) / 127.0f, -1.0f, 1.0f);
+    }
+}
+
 // Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit
 // floating-point representation found in the OpenGL ES Specification, and then packing these
 // two 16-bit integers into a 32-bit unsigned integer.
diff --git a/src/common/mathutil_unittest.cpp b/src/common/mathutil_unittest.cpp
index 0c35305..3f3ded9 100644
--- a/src/common/mathutil_unittest.cpp
+++ b/src/common/mathutil_unittest.cpp
@@ -142,6 +142,56 @@
     }
 }
 
+// Test the correctness of packUnorm4x8 and unpackUnorm4x8 functions.
+// For floats f1 to f4, unpackUnorm4x8(packUnorm4x8(f1, f2, f3, f4)) should be same as f1 to f4.
+TEST(MathUtilTest, packAndUnpackUnorm4x8)
+{
+    const float input[5][4] = {{0.0f, 0.0f, 0.0f, 0.0f},
+                               {1.0f, 1.0f, 1.0f, 1.0f},
+                               {-1.0f, 1.0f, -1.0f, 1.0f},
+                               {-1.0f, -1.0f, -1.0f, -1.0f},
+                               {64.0f / 255.0f, 128.0f / 255.0f, 32.0f / 255.0f, 16.0f / 255.0f}};
+
+    const float floatFaultTolerance = 0.005f;
+    float outputVals[4];
+
+    for (size_t i = 0; i < 5; i++)
+    {
+        UnpackUnorm4x8(PackUnorm4x8(input[i][0], input[i][1], input[i][2], input[i][3]),
+                       outputVals);
+        for (size_t j = 0; j < 4; j++)
+        {
+            float expected = input[i][j] < 0.0f ? 0.0f : input[i][j];
+            EXPECT_NEAR(expected, outputVals[j], floatFaultTolerance);
+        }
+    }
+}
+
+// Test the correctness of packSnorm4x8 and unpackSnorm4x8 functions.
+// For floats f1 to f4, unpackSnorm4x8(packSnorm4x8(f1, f2, f3, f4)) should be same as f1 to f4.
+TEST(MathUtilTest, packAndUnpackSnorm4x8)
+{
+    const float input[5][4] = {{0.0f, 0.0f, 0.0f, 0.0f},
+                               {1.0f, 1.0f, 1.0f, 1.0f},
+                               {-1.0f, 1.0f, -1.0f, 1.0f},
+                               {-1.0f, -1.0f, -1.0f, -1.0f},
+                               {64.0f / 127.0f, -8.0f / 127.0f, 32.0f / 127.0f, 16.0f / 127.0f}};
+
+    const float floatFaultTolerance = 0.01f;
+    float outputVals[4];
+
+    for (size_t i = 0; i < 5; i++)
+    {
+        UnpackSnorm4x8(PackSnorm4x8(input[i][0], input[i][1], input[i][2], input[i][3]),
+                       outputVals);
+        for (size_t j = 0; j < 4; j++)
+        {
+            float expected = input[i][j];
+            EXPECT_NEAR(expected, outputVals[j], floatFaultTolerance);
+        }
+    }
+}
+
 // Test the correctness of gl::isNaN function.
 TEST(MathUtilTest, isNaN)
 {
diff --git a/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
index d0f4dfa..3f8acde 100644
--- a/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
+++ b/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
@@ -297,23 +297,23 @@
         "}\n");
 
     emu->addEmulatedFunction(EOpPackSnorm2x16, float2,
-                             "int webgl_toSnorm(in float x) {\n"
+                             "int webgl_toSnorm16(in float x) {\n"
                              "    return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n"
                              "}\n"
                              "\n"
                              "uint webgl_packSnorm2x16_emu(in float2 v) {\n"
-                             "    int x = webgl_toSnorm(v.x);\n"
-                             "    int y = webgl_toSnorm(v.y);\n"
+                             "    int x = webgl_toSnorm16(v.x);\n"
+                             "    int y = webgl_toSnorm16(v.y);\n"
                              "    return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n"
                              "}\n");
     emu->addEmulatedFunction(EOpPackUnorm2x16, float2,
-                             "uint webgl_toUnorm(in float x) {\n"
+                             "uint webgl_toUnorm16(in float x) {\n"
                              "    return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n"
                              "}\n"
                              "\n"
                              "uint webgl_packUnorm2x16_emu(in float2 v) {\n"
-                             "    uint x = webgl_toUnorm(v.x);\n"
-                             "    uint y = webgl_toUnorm(v.y);\n"
+                             "    uint x = webgl_toUnorm16(v.x);\n"
+                             "    uint y = webgl_toUnorm16(v.y);\n"
                              "    return (y << 16) | x;\n"
                              "}\n");
     emu->addEmulatedFunction(EOpPackHalf2x16, float2,
@@ -324,7 +324,7 @@
                              "}\n");
 
     emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1,
-                             "float webgl_fromSnorm(in uint x) {\n"
+                             "float webgl_fromSnorm16(in uint x) {\n"
                              "    int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);\n"
                              "    return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
                              "}\n"
@@ -332,17 +332,17 @@
                              "float2 webgl_unpackSnorm2x16_emu(in uint u) {\n"
                              "    uint y = (u >> 16);\n"
                              "    uint x = u;\n"
-                             "    return float2(webgl_fromSnorm(x), webgl_fromSnorm(y));\n"
+                             "    return float2(webgl_fromSnorm16(x), webgl_fromSnorm16(y));\n"
                              "}\n");
     emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1,
-                             "float webgl_fromUnorm(in uint x) {\n"
+                             "float webgl_fromUnorm16(in uint x) {\n"
                              "    return float(x) / 65535.0;\n"
                              "}\n"
                              "\n"
                              "float2 webgl_unpackUnorm2x16_emu(in uint u) {\n"
                              "    uint y = (u >> 16);\n"
                              "    uint x = u & 0xffffu;\n"
-                             "    return float2(webgl_fromUnorm(x), webgl_fromUnorm(y));\n"
+                             "    return float2(webgl_fromUnorm16(x), webgl_fromUnorm16(y));\n"
                              "}\n");
     emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1,
                              "float2 webgl_unpackHalf2x16_emu(in uint u) {\n"
@@ -351,6 +351,60 @@
                              "    return float2(f16tof32(x), f16tof32(y));\n"
                              "}\n");
 
+    emu->addEmulatedFunction(EOpPackSnorm4x8, float4,
+                             "int webgl_toSnorm8(in float x) {\n"
+                             "    return int(round(clamp(x, -1.0, 1.0) * 127.0));\n"
+                             "}\n"
+                             "\n"
+                             "uint webgl_packSnorm4x8_emu(in float4 v) {\n"
+                             "    int x = webgl_toSnorm8(v.x);\n"
+                             "    int y = webgl_toSnorm8(v.y);\n"
+                             "    int z = webgl_toSnorm8(v.z);\n"
+                             "    int w = webgl_toSnorm8(v.w);\n"
+                             "    return ((asuint(w) & 0xffu) << 24) | ((asuint(z) & 0xffu) << 16) "
+                             "| ((asuint(y) & 0xffu) << 8) | (asuint(x) & 0xffu);\n"
+                             "}\n");
+    emu->addEmulatedFunction(EOpPackUnorm4x8, float4,
+                             "uint webgl_toUnorm8(in float x) {\n"
+                             "    return uint(round(clamp(x, 0.0, 1.0) * 255.0));\n"
+                             "}\n"
+                             "\n"
+                             "uint webgl_packUnorm4x8_emu(in float4 v) {\n"
+                             "    uint x = webgl_toUnorm8(v.x);\n"
+                             "    uint y = webgl_toUnorm8(v.y);\n"
+                             "    uint z = webgl_toUnorm8(v.z);\n"
+                             "    uint w = webgl_toUnorm8(v.w);\n"
+                             "    return (w << 24) | (z << 16) | (y << 8) | x;\n"
+                             "}\n");
+
+    emu->addEmulatedFunction(EOpUnpackSnorm4x8, uint1,
+                             "float webgl_fromSnorm8(in uint x) {\n"
+                             "    int xi = asint(x & 0x7fu) - asint(x & 0x80u);\n"
+                             "    return clamp(float(xi) / 127.0, -1.0, 1.0);\n"
+                             "}\n"
+                             "\n"
+                             "float4 webgl_unpackSnorm4x8_emu(in uint u) {\n"
+                             "    uint w = (u >> 24);\n"
+                             "    uint z = (u >> 16);\n"
+                             "    uint y = (u >> 8);\n"
+                             "    uint x = u;\n"
+                             "    return float4(webgl_fromSnorm8(x), webgl_fromSnorm8(y), "
+                             "webgl_fromSnorm8(z), webgl_fromSnorm8(w));\n"
+                             "}\n");
+    emu->addEmulatedFunction(EOpUnpackUnorm4x8, uint1,
+                             "float webgl_fromUnorm8(in uint x) {\n"
+                             "    return float(x) / 255.0;\n"
+                             "}\n"
+                             "\n"
+                             "float4 webgl_unpackUnorm4x8_emu(in uint u) {\n"
+                             "    uint w = (u >> 24) & 0xffu;\n"
+                             "    uint z = (u >> 16) & 0xffu;\n"
+                             "    uint y = (u >> 8) & 0xffu;\n"
+                             "    uint x = u & 0xffu;\n"
+                             "    return float4(webgl_fromUnorm8(x), webgl_fromUnorm8(y), "
+                             "webgl_fromUnorm8(z), webgl_fromUnorm8(w));\n"
+                             "}\n");
+
     // The matrix resulting from outer product needs to be transposed
     // (matrices are stored as transposed to simplify element access in HLSL).
     // So the function should return transpose(c * r) where c is a column vector
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index e016a10..8a6a63a 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -128,6 +128,11 @@
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, uint1);
     symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, uint1);
 
+    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackUnorm4x8, uint1, float4);
+    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackSnorm4x8, uint1, float4);
+    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackUnorm4x8, float4, uint1);
+    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackSnorm4x8, float4, uint1);
+
     //
     // Geometric Functions.
     //
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 276b653..4039305 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -821,6 +821,8 @@
         case EOpPackSnorm2x16:
         case EOpPackUnorm2x16:
         case EOpPackHalf2x16:
+        case EOpPackUnorm4x8:
+        case EOpPackSnorm4x8:
             setType(TType(EbtUInt, EbpHigh, resultQualifier));
             break;
         case EOpUnpackSnorm2x16:
@@ -830,6 +832,10 @@
         case EOpUnpackHalf2x16:
             setType(TType(EbtFloat, EbpMedium, resultQualifier, 2));
             break;
+        case EOpUnpackUnorm4x8:
+        case EOpUnpackSnorm4x8:
+            setType(TType(EbtFloat, EbpMedium, resultQualifier, 4));
+            break;
         case EOpAny:
         case EOpAll:
             setType(TType(EbtBool, EbpUndefined, resultQualifier));
@@ -1315,6 +1321,10 @@
         case EOpUnpackUnorm2x16:
         case EOpPackHalf2x16:
         case EOpUnpackHalf2x16:
+        case EOpPackUnorm4x8:
+        case EOpPackSnorm4x8:
+        case EOpUnpackUnorm4x8:
+        case EOpUnpackSnorm4x8:
             constArray = operandConstant->foldUnaryNonComponentWise(mOp);
             break;
         default:
@@ -1868,6 +1878,49 @@
             break;
         }
 
+        case EOpPackUnorm4x8:
+        {
+            ASSERT(getType().getBasicType() == EbtFloat);
+            resultArray = new TConstantUnion();
+            resultArray->setUConst(
+                gl::PackUnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
+                                 operandArray[2].getFConst(), operandArray[3].getFConst()));
+            break;
+        }
+        case EOpPackSnorm4x8:
+        {
+            ASSERT(getType().getBasicType() == EbtFloat);
+            resultArray = new TConstantUnion();
+            resultArray->setUConst(
+                gl::PackSnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
+                                 operandArray[2].getFConst(), operandArray[3].getFConst()));
+            break;
+        }
+        case EOpUnpackUnorm4x8:
+        {
+            ASSERT(getType().getBasicType() == EbtUInt);
+            resultArray = new TConstantUnion[4];
+            float f[4];
+            gl::UnpackUnorm4x8(operandArray[0].getUConst(), f);
+            for (size_t i = 0; i < 4; ++i)
+            {
+                resultArray[i].setFConst(f[i]);
+            }
+            break;
+        }
+        case EOpUnpackSnorm4x8:
+        {
+            ASSERT(getType().getBasicType() == EbtUInt);
+            resultArray = new TConstantUnion[4];
+            float f[4];
+            gl::UnpackSnorm4x8(operandArray[0].getUConst(), f);
+            for (size_t i = 0; i < 4; ++i)
+            {
+                resultArray[i].setFConst(f[i]);
+            }
+            break;
+        }
+
         default:
             UNREACHABLE();
             break;
diff --git a/src/compiler/translator/Operator.cpp b/src/compiler/translator/Operator.cpp
index 12ae1a9..64e8052 100644
--- a/src/compiler/translator/Operator.cpp
+++ b/src/compiler/translator/Operator.cpp
@@ -210,6 +210,15 @@
         case EOpUnpackHalf2x16:
             return "unpackHalf2x16";
 
+        case EOpPackUnorm4x8:
+            return "packUnorm4x8";
+        case EOpPackSnorm4x8:
+            return "packSnorm4x8";
+        case EOpUnpackUnorm4x8:
+            return "unpackUnorm4x8";
+        case EOpUnpackSnorm4x8:
+            return "unpackSnorm4x8";
+
         case EOpLength:
             return "length";
         case EOpDistance:
diff --git a/src/compiler/translator/Operator.h b/src/compiler/translator/Operator.h
index 968dbac..18e7ca5 100644
--- a/src/compiler/translator/Operator.h
+++ b/src/compiler/translator/Operator.h
@@ -150,6 +150,11 @@
     EOpUnpackUnorm2x16,
     EOpUnpackHalf2x16,
 
+    EOpPackUnorm4x8,
+    EOpPackSnorm4x8,
+    EOpUnpackUnorm4x8,
+    EOpUnpackSnorm4x8,
+
     EOpLength,
     EOpDistance,
     EOpDot,
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 3a2a757..4ae8651 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -714,6 +714,10 @@
         case EOpUnpackSnorm2x16:
         case EOpUnpackUnorm2x16:
         case EOpUnpackHalf2x16:
+        case EOpPackUnorm4x8:
+        case EOpPackSnorm4x8:
+        case EOpUnpackUnorm4x8:
+        case EOpUnpackSnorm4x8:
         case EOpLength:
         case EOpNormalize:
         case EOpDFdx:
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 8a3794d..df0fa9f 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -1414,6 +1414,10 @@
         case EOpUnpackSnorm2x16:
         case EOpUnpackUnorm2x16:
         case EOpUnpackHalf2x16:
+        case EOpPackUnorm4x8:
+        case EOpPackSnorm4x8:
+        case EOpUnpackUnorm4x8:
+        case EOpUnpackSnorm4x8:
             ASSERT(node->getUseEmulatedFunction());
             writeEmulatedFunctionTriplet(out, visit, node->getOp());
             break;
diff --git a/src/tests/compiler_tests/ConstantFolding_test.cpp b/src/tests/compiler_tests/ConstantFolding_test.cpp
index 270d361..9bfce5b 100644
--- a/src/tests/compiler_tests/ConstantFolding_test.cpp
+++ b/src/tests/compiler_tests/ConstantFolding_test.cpp
@@ -1353,3 +1353,59 @@
     evaluateInt(intString);
     ASSERT_TRUE(constantFoundInAST(-1));
 }
+
+// Test that packUnorm4x8 is folded correctly for a vector of zeroes.
+TEST_F(ConstantFoldingExpressionTest, FoldPackUnorm4x8Zero)
+{
+    const std::string &intString = "packUnorm4x8(vec4(0.0))";
+    evaluateUint(intString);
+    ASSERT_TRUE(constantFoundInAST(0u));
+}
+
+// Test that packUnorm4x8 is folded correctly for a vector of ones.
+TEST_F(ConstantFoldingExpressionTest, FoldPackUnorm4x8One)
+{
+    const std::string &intString = "packUnorm4x8(vec4(1.0))";
+    evaluateUint(intString);
+    ASSERT_TRUE(constantFoundInAST(0xffffffffu));
+}
+
+// Test that packSnorm4x8 is folded correctly for a vector of zeroes.
+TEST_F(ConstantFoldingExpressionTest, FoldPackSnorm4x8Zero)
+{
+    const std::string &intString = "packSnorm4x8(vec4(0.0))";
+    evaluateUint(intString);
+    ASSERT_TRUE(constantFoundInAST(0u));
+}
+
+// Test that packSnorm4x8 is folded correctly for a vector of ones.
+TEST_F(ConstantFoldingExpressionTest, FoldPackSnorm4x8One)
+{
+    const std::string &intString = "packSnorm4x8(vec4(1.0))";
+    evaluateUint(intString);
+    ASSERT_TRUE(constantFoundInAST(0x7f7f7f7fu));
+}
+
+// Test that packSnorm4x8 is folded correctly for a vector of minus ones.
+TEST_F(ConstantFoldingExpressionTest, FoldPackSnorm4x8MinusOne)
+{
+    const std::string &intString = "packSnorm4x8(vec4(-1.0))";
+    evaluateUint(intString);
+    ASSERT_TRUE(constantFoundInAST(0x81818181u));
+}
+
+// Test that unpackSnorm4x8 is folded correctly when it needs to clamp the result.
+TEST_F(ConstantFoldingExpressionTest, FoldUnpackSnorm4x8Clamp)
+{
+    const std::string &floatString = "unpackSnorm4x8(0x00000080u).x";
+    evaluateFloat(floatString);
+    ASSERT_TRUE(constantFoundInAST(-1.0f));
+}
+
+// Test that unpackUnorm4x8 is folded correctly.
+TEST_F(ConstantFoldingExpressionTest, FoldUnpackUnorm4x8)
+{
+    const std::string &floatString = "unpackUnorm4x8(0x007bbeefu).z";
+    evaluateFloat(floatString);
+    ASSERT_TRUE(constantFoundInAST(123.0f / 255.0f));
+}
diff --git a/src/tests/deqp_support/deqp_gles31_test_expectations.txt b/src/tests/deqp_support/deqp_gles31_test_expectations.txt
index f228a74..40646c3 100644
--- a/src/tests/deqp_support/deqp_gles31_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles31_test_expectations.txt
@@ -446,29 +446,13 @@
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uint_highp_compute = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uvec2_highp_compute = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.common.uintbitstofloat.uvec3_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_lowp_vertex = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_lowp_fragment = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_mediump_vertex = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_mediump_fragment = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_highp_vertex = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_highp_fragment = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm4x8_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpacksnorm4x8_vertex = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpacksnorm4x8_fragment = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpacksnorm4x8_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_lowp_vertex = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_lowp_fragment = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_lowp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_mediump_vertex = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_mediump_fragment = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_mediump_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_highp_vertex = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_highp_fragment = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packunorm4x8_highp_compute = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackunorm4x8_vertex = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackunorm4x8_fragment = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.unpackunorm4x8_compute = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_lowp_compute = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.pack_unpack.packsnorm2x16_mediump_compute = FAIL
diff --git a/src/tests/test_utils/ConstantFoldingTest.cpp b/src/tests/test_utils/ConstantFoldingTest.cpp
index d058c9f..b9b508b 100644
--- a/src/tests/test_utils/ConstantFoldingTest.cpp
+++ b/src/tests/test_utils/ConstantFoldingTest.cpp
@@ -18,7 +18,7 @@
 void ConstantFoldingExpressionTest::evaluateFloat(const std::string &floatExpression)
 {
     std::stringstream shaderStream;
-    shaderStream << "#version 300 es\n"
+    shaderStream << "#version 310 es\n"
                     "precision mediump float;\n"
                     "out float my_FragColor;\n"
                     "void main()\n"