ES31: Support images in the compiler on D3D backend.

BUG=angleproject:1987
TEST=angle_end2end_tests

Change-Id: I83f5f9ffda7e676a8f98b963d1f1c50e9463faf4
Reviewed-on: https://chromium-review.googlesource.com/706247
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index b00ab78..54427a9 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -16,6 +16,7 @@
 #include "compiler/translator/BuiltInFunctionEmulator.h"
 #include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
 #include "compiler/translator/FlagStd140Structs.h"
+#include "compiler/translator/ImageFunctionHLSL.h"
 #include "compiler/translator/InfoSink.h"
 #include "compiler/translator/NodeSearch.h"
 #include "compiler/translator/RemoveSwitchFallThrough.h"
@@ -165,8 +166,9 @@
     mExcessiveLoopIndex = nullptr;
 
     mStructureHLSL       = new StructureHLSL;
-    mUniformHLSL         = new UniformHLSL(mStructureHLSL, outputType, uniforms);
+    mUniformHLSL         = new UniformHLSL(shaderType, mStructureHLSL, outputType, uniforms);
     mTextureFunctionHLSL = new TextureFunctionHLSL;
+    mImageFunctionHLSL   = new ImageFunctionHLSL;
 
     if (mOutputType == SH_HLSL_3_0_OUTPUT)
     {
@@ -186,6 +188,7 @@
     SafeDelete(mStructureHLSL);
     SafeDelete(mUniformHLSL);
     SafeDelete(mTextureFunctionHLSL);
+    SafeDelete(mImageFunctionHLSL);
     for (auto &eqFunction : mStructEqualityFunctions)
     {
         SafeDelete(eqFunction);
@@ -731,6 +734,7 @@
     bool getDimensionsIgnoresBaseLevel =
         (mCompileOptions & SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL) != 0;
     mTextureFunctionHLSL->textureFunctionHeader(out, mOutputType, getDimensionsIgnoresBaseLevel);
+    mImageFunctionHLSL->imageFunctionHeader(out);
 
     if (mUsesFragCoord)
     {
@@ -1865,6 +1869,15 @@
                 // AST, such as precision emulation functions.
                 out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj()) << "(";
             }
+            else if (node->getFunctionSymbolInfo()->isImageFunction())
+            {
+                TString name              = node->getFunctionSymbolInfo()->getName();
+                TType type                = (*arguments)[0]->getAsTyped()->getType();
+                TString imageFunctionName = mImageFunctionHLSL->useImageFunction(
+                    name, type.getBasicType(), type.getLayoutQualifier().imageInternalFormat,
+                    type.getMemoryQualifier().readonly);
+                out << imageFunctionName << "(";
+            }
             else
             {
                 const TString &name    = node->getFunctionSymbolInfo()->getName();