spirv-reader: Support depth-reference sampling

Bug: tint:109
Change-Id: I1e1dcd7c0724124a3a29e94e65856a07c54dd998
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34005
Commit-Queue: David Neto <dneto@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Auto-Submit: David Neto <dneto@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 8276813..5d1e5c4 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -3654,6 +3654,7 @@
   // TODO(dneto): For arrayed access, split off the array layer.
   params.push_back(MakeOperand(inst, 1).expr);
   uint32_t arg_index = 2;
+  const auto num_args = inst.NumInOperands();
 
   std::string builtin_name;
   switch (inst.opcode()) {
@@ -3661,6 +3662,18 @@
     case SpvOpImageSampleExplicitLod:
       builtin_name = "textureSample";
       break;
+    case SpvOpImageSampleDrefImplicitLod:
+    case SpvOpImageSampleDrefExplicitLod:
+      builtin_name = "textureSampleCompare";
+      if (arg_index < num_args) {
+        params.push_back(MakeOperand(inst, arg_index).expr);
+        arg_index++;
+      } else {
+        return Fail()
+               << "image depth-compare instruction is missing a Dref operand: "
+               << inst.PrettyPrint();
+      }
+      break;
     case SpvOpImageGather:
     case SpvOpImageDrefGather:
       return Fail() << " image gather is not yet supported";
@@ -3672,7 +3685,6 @@
 
   // Loop over the image operands, looking for extra operands to the builtin.
   // Except we uroll the loop.
-  const auto num_args = inst.NumInOperands();
   uint32_t image_operands_mask = 0;
   if (arg_index < num_args) {
     image_operands_mask = inst.GetSingleWordInOperand(arg_index);
diff --git a/src/reader/spirv/parser_impl_handle_test.cc b/src/reader/spirv/parser_impl_handle_test.cc
index 79e1401..07eb3f5 100644
--- a/src/reader/spirv/parser_impl_handle_test.cc
+++ b/src/reader/spirv/parser_impl_handle_test.cc
@@ -1195,6 +1195,8 @@
      OpDecorate %20 DescriptorSet 2
      OpDecorate %20 Binding 1
 )" + CommonTypes() + R"(
+     ; Vulkan ignores the "depth" parameter on OpTypeImage.
+     ; So this image type can serve for both regular sampling and depth-compare.
      %si_ty = OpTypeSampledImage %f_texture_2d
      %coords = OpConstantNull %v2float
 
@@ -1453,19 +1455,93 @@
         ));
 
 INSTANTIATE_TEST_SUITE_P(
-    DISABLED_ImageSampleDrefImplicitLod,
+    ImageSampleDrefImplicitLod,
     SpvParserTest_DeclHandle_SampledImage,
-    ::testing::ValuesIn(std::vector<DeclSampledImageCase>{
-        // TODO(dneto): ImageSampleDrefImplicitLod
-        // TODO(dneto): ImageSampleDrefImplicitLod with ConstOffset (signed and
-        // unsigned)
-        // TODO(dneto): ImageSampleDrefImplicitLod with Bias
-        // TODO(dneto): ImageSampleDrefImplicitLod with Biase and ConstOffset
-        // (signed and unsigned)
-    }));
+    ::testing::Values(
+        // ImageSampleDrefImplicitLod
+        DeclSampledImageCase{"%result = OpImageSampleDrefImplicitLod "
+                             "%v4float %sampled_image %coords %depth",
+                             R"(
+  DecoratedVariable{
+    Decorations{
+      SetDecoration{0}
+      BindingDecoration{0}
+    }
+    x_10
+    uniform_constant
+    __sampler_comparison
+  }
+  DecoratedVariable{
+    Decorations{
+      SetDecoration{2}
+      BindingDecoration{1}
+    }
+    x_20
+    uniform_constant
+    __depth_texture_2d
+  })",
+                             R"(
+          Call[not set]{
+            Identifier[not set]{textureSampleCompare}
+            (
+              Identifier[not set]{x_20}
+              Identifier[not set]{x_10}
+              TypeConstructor[not set]{
+                __vec_2__f32
+                ScalarConstructor[not set]{0.000000}
+                ScalarConstructor[not set]{0.000000}
+              }
+              ScalarConstructor[not set]{0.200000}
+            )
+          })"},
+
+        // ImageSampleDrefImplicitLod with ConstOffset
+        DeclSampledImageCase{
+            "%result = OpImageSampleDrefImplicitLod %v4float "
+            "%sampled_image %coords %depth ConstOffset %offsets2d",
+            R"(
+  DecoratedVariable{
+    Decorations{
+      SetDecoration{0}
+      BindingDecoration{0}
+    }
+    x_10
+    uniform_constant
+    __sampler_comparison
+  }
+  DecoratedVariable{
+    Decorations{
+      SetDecoration{2}
+      BindingDecoration{1}
+    }
+    x_20
+    uniform_constant
+    __depth_texture_2d
+  })",
+            R"(
+          Call[not set]{
+            Identifier[not set]{textureSampleCompare}
+            (
+              Identifier[not set]{x_20}
+              Identifier[not set]{x_10}
+              TypeConstructor[not set]{
+                __vec_2__f32
+                ScalarConstructor[not set]{0.000000}
+                ScalarConstructor[not set]{0.000000}
+              }
+              ScalarConstructor[not set]{0.200000}
+              TypeConstructor[not set]{
+                __vec_2__i32
+                ScalarConstructor[not set]{3}
+                ScalarConstructor[not set]{4}
+              }
+            )
+          })"}
+
+        ));
 
 INSTANTIATE_TEST_SUITE_P(
-    DisabledimageSampleExplicitLod,
+    ImageSampleExplicitLod,
     SpvParserTest_DeclHandle_SampledImage,
     ::testing::Values(