Add support for images in the compiler

The patch adds support for GLSL ES 3.1 image types.

Internal format layout qualifiers for images are added.

Support for the readonly and writeonly qualifiers are added. The other
memory qualifiers are omitted as to make the patch simpler.

Tests are added which check for correct and incorrect usage of images,
internal format layout and memory qualifiers.

BUG=angleproject:1442

TEST=angle_unittests
TEST=angle_end2end_tests

Change-Id: Ie4d3acb2a195de11b405ad54110a04c4c1de0b7e
Reviewed-on: https://chromium-review.googlesource.com/378855
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index aa23776..92121e8 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -249,6 +249,43 @@
         insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
         insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
     }
+    else if (IsGImage(ptype1->getBasicType()))
+    {
+        insertUnmangledBuiltIn(name);
+
+        const TType *floatType    = TCache::getType(EbtFloat, 4);
+        const TType *intType      = TCache::getType(EbtInt, 4);
+        const TType *unsignedType = TCache::getType(EbtUInt, 4);
+
+        const TType *floatImage =
+            TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
+        const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
+        const TType *unsignedImage =
+            TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
+
+        // GLSL ES 3.10, Revision 4, 8.12 Image Functions
+        if (rvalue->getBasicType() == EbtGVec4)
+        {
+            // imageLoad
+            insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
+            insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
+            insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
+        }
+        else if (rvalue->getBasicType() == EbtVoid)
+        {
+            // imageStore
+            insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
+            insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
+            insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
+        }
+        else
+        {
+            // imageSize
+            insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
+            insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
+            insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
+        }
+    }
     else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
     {
         ASSERT(!ptype4 && !ptype5);