spirv-reader: sampling depth texture requires unsigned Lod

Fixed: tint:378
Change-Id: I835ee7e9fb63dc68db571091f28fd34287c209b0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/34201
Commit-Queue: David Neto <dneto@google.com>
Auto-Submit: David Neto <dneto@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 0f64d8e..027cacc 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -3704,7 +3704,21 @@
   }
   if (arg_index < num_args && (image_operands_mask & SpvImageOperandsLodMask)) {
     builtin_name += "Level";
-    params.push_back(MakeOperand(inst, arg_index).expr);
+    auto* lod_operand = MakeOperand(inst, arg_index).expr;
+    // When sampling from a depth texture, the Lod operand must be an unsigned
+    // integer.
+    if (ast::type::PointerType* type =
+            parser_impl_.GetTypeForHandleVar(*image)) {
+      if (ast::type::TextureType* texture_type = type->type()->AsTexture()) {
+        if (texture_type->IsDepth()) {
+          // Convert it to an unsigned integer type.
+          lod_operand = ast_module_.create<ast::TypeConstructorExpression>(
+              ast_module_.create<ast::type::U32Type>(),
+              ast::ExpressionList{lod_operand});
+        }
+      }
+    }
+    params.push_back(lod_operand);
     image_operands_mask ^= SpvImageOperandsLodMask;
     arg_index++;
   }
diff --git a/src/reader/spirv/parser_impl_handle_test.cc b/src/reader/spirv/parser_impl_handle_test.cc
index 54bb3a6..6c72b50 100644
--- a/src/reader/spirv/parser_impl_handle_test.cc
+++ b/src/reader/spirv/parser_impl_handle_test.cc
@@ -2198,6 +2198,86 @@
             )
           })"}));
 
+// Test crbug.com/378:
+// In WGSL, sampling from depth texture with explicit level of detail
+// requires the Lod parameter as an unsigned integer.
+// This corresponds to SPIR-V OpSampleExplicitLod and WGSL textureSampleLevel.
+INSTANTIATE_TEST_SUITE_P(
+    ImageSampleExplicitLod_DepthTexture,
+    SpvParserTest_DeclHandle_SampledImage,
+    ::testing::ValuesIn(std::vector<SampledImageCase>{
+        // Test a non-depth case.
+        // (This is already tested above in the ImageSampleExplicitLod suite,
+        // but I'm repeating here for the contrast with the depth case.)
+        {"%float 2D 0 0 0 1 Unknown",
+         "%result = OpImageSampleExplicitLod %v4float "
+         "%sampled_image %vf12 Lod %f1",
+         R"(
+  DecoratedVariable{
+    Decorations{
+      SetDecoration{0}
+      BindingDecoration{0}
+    }
+    x_10
+    uniform_constant
+    __sampler_sampler
+  }
+  DecoratedVariable{
+    Decorations{
+      SetDecoration{2}
+      BindingDecoration{1}
+    }
+    x_20
+    uniform_constant
+    __sampled_texture_2d__f32
+  })",
+         R"(
+          Call[not set]{
+            Identifier[not set]{textureSampleLevel}
+            (
+              Identifier[not set]{x_20}
+              Identifier[not set]{x_10}
+              Identifier[not set]{vf12}
+              Identifier[not set]{f1}
+            )
+          })"},
+        // Test a depth case
+        {"%float 2D 1 0 0 1 Unknown",
+         "%result = OpImageSampleExplicitLod %v4float "
+         "%sampled_image %vf12 Lod %f1",
+         R"(
+  DecoratedVariable{
+    Decorations{
+      SetDecoration{0}
+      BindingDecoration{0}
+    }
+    x_10
+    uniform_constant
+    __sampler_sampler
+  }
+  DecoratedVariable{
+    Decorations{
+      SetDecoration{2}
+      BindingDecoration{1}
+    }
+    x_20
+    uniform_constant
+    __depth_texture_2d
+  })",
+         R"(
+          Call[not set]{
+            Identifier[not set]{textureSampleLevel}
+            (
+              Identifier[not set]{x_20}
+              Identifier[not set]{x_10}
+              Identifier[not set]{vf12}
+              TypeConstructor[not set]{
+                __u32
+                Identifier[not set]{f1}
+              }
+            )
+          })"}}));
+
 struct ImageCoordsCase {
   // SPIR-V image type, excluding result ID and opcode
   std::string spirv_image_type_details;