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;