ES31: Support textureGather[Offset] on shadow samplers

This patch implements translating textureGather[Offset] into HLSL
when the sampler is a shadow sampler. The related HLSL function
should be GatherCmp().

According to the definition of textureGatherOffset():
([ESSL 3.1] Chapter 8.9.3 Page 138)
- gvec4 textureGatherOffset(gsampler2D sampler, vec2 P,
  ivec2 offset, [,int comp])
- vec4 textureGatherOffset(sampler2DShadow sampler, vec2 P,
  float refZ, ivec2 offset)
We need to add parameter "refZ" before "offset" when the sampler
is a shadow sampler.

Bug: angleproject:2826
Test: dEQP-GLES31.functional.texture.gather.basic.2d.depth32f.*
     dEQP-GLES31.functional.texture.gather.basic.2d_array.depth32f.*
     dEQP-GLES31.functional.texture.gather.basic.cube.depth32f.*
     dEQP-GLES31.functional.texture.gather.offset.min_required_offset.2d.depth32f.*
     dEQP-GLES31.functional.texture.gather.offset.min_required_offset.2d_array.depth32f.*
     dEQP-GLES31.functional.texture.gather.offset.implementation_offset.2d.depth32f.*
     dEQP-GLES31.functional.texture.gather.offset.implementation_offset.2d_array.depth32f.*

Change-Id: I9a7d095dd3cfa41aaefd14d012ed1f309abfc6d5
Reviewed-on: https://chromium-review.googlesource.com/c/1244081
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Jiajia Qin <jiajia.qin@intel.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/TextureFunctionHLSL.cpp b/src/compiler/translator/TextureFunctionHLSL.cpp
index 164922f..ad28eea 100644
--- a/src/compiler/translator/TextureFunctionHLSL.cpp
+++ b/src/compiler/translator/TextureFunctionHLSL.cpp
@@ -387,6 +387,12 @@
             UNREACHABLE();
     }
 
+    if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GATHER &&
+        IsShadowSampler(textureFunction.sampler))
+    {
+        out << ", float refZ";
+    }
+
     if (textureFunction.offset)
     {
         switch (textureFunction.sampler)
@@ -418,7 +424,8 @@
     {
         out << ", float bias";
     }
-    else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GATHER)
+    else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GATHER &&
+             !IsShadowSampler(textureFunction.sampler))
     {
         out << ", int comp = 0";
     }
@@ -850,6 +857,18 @@
 
     ImmutableString samplerCoordString(samplerCoordBuilder);
 
+    if (IsShadowSampler(textureFunction.sampler))
+    {
+        out << "return " << textureReference << ".GatherCmp(" << samplerReference << ", "
+            << samplerCoordString << ", refZ";
+        if (textureFunction.offset)
+        {
+            out << ", offset";
+        }
+        out << ");\n";
+        return;
+    }
+
     constexpr std::array<const char *, 4> kHLSLGatherFunctions = {
         {"GatherRed", "GatherGreen", "GatherBlue", "GatherAlpha"}};
 
@@ -1211,7 +1230,14 @@
             case EbtSampler2DShadow:
             case EbtSamplerCubeShadow:
             case EbtSampler2DArrayShadow:
-                return "float";
+                if (method == TextureFunctionHLSL::TextureFunction::GATHER)
+                {
+                    return "float4";
+                }
+                else
+                {
+                    return "float";
+                }
             default:
                 UNREACHABLE();
         }