[spirv-reader][ir] Support OpImageSampleDrefExplicitLod Handle the `OpImageSampleDrefExplicitLod` instruction, converting the texture to depth texture and sampler to sampler_comparison as needed. Bug: 407384678 Change-Id: I2440bf0409fc6c75194d2edfc633d7482fa8547b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/248297 Reviewed-by: James Price <jrprice@google.com> Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/spirv/reader/lower/builtins.cc b/src/tint/lang/spirv/reader/lower/builtins.cc index ec04027..9bf7fb3 100644 --- a/src/tint/lang/spirv/reader/lower/builtins.cc +++ b/src/tint/lang/spirv/reader/lower/builtins.cc
@@ -248,6 +248,7 @@ case spirv::BuiltinFn::kImageSampleProjImplicitLod: case spirv::BuiltinFn::kImageSampleProjExplicitLod: case spirv::BuiltinFn::kImageSampleDrefImplicitLod: + case spirv::BuiltinFn::kImageSampleDrefExplicitLod: case spirv::BuiltinFn::kImageWrite: // Ignore image methods, they'll be handled by the `Texture` transform. break;
diff --git a/src/tint/lang/spirv/reader/lower/texture.cc b/src/tint/lang/spirv/reader/lower/texture.cc index 8ecbbee..eb7791c 100644 --- a/src/tint/lang/spirv/reader/lower/texture.cc +++ b/src/tint/lang/spirv/reader/lower/texture.cc
@@ -150,6 +150,7 @@ builtin_worklist.Push(builtin); break; case spirv::BuiltinFn::kImageSampleDrefImplicitLod: + case spirv::BuiltinFn::kImageSampleDrefExplicitLod: depth_worklist.Push(builtin); break; default: @@ -167,6 +168,7 @@ for (auto* builtin : depth_worklist) { switch (builtin->Func()) { case spirv::BuiltinFn::kImageSampleDrefImplicitLod: + case spirv::BuiltinFn::kImageSampleDrefExplicitLod: ImageSampleDref(builtin); break; default: @@ -624,12 +626,19 @@ ProcessCoords(tex_ty, false, coords, new_args); new_args.Push(depth); + auto fn = core::BuiltinFn::kTextureSampleCompare; + if (HasLod(operand_mask)) { + fn = core::BuiltinFn::kTextureSampleCompareLevel; + idx++; // Skip over the index + + // Metal only supports Lod = 0 for comparison sampling without derivatives. So, WGSL + // doesn't take a level value, drop the LOD param. + } if (HasConstOffset(operand_mask)) { ProcessOffset(args[idx++], new_args); } - b.CallWithResult(call->DetachResult(), core::BuiltinFn::kTextureSampleCompare, - new_args); + b.CallWithResult(call->DetachResult(), fn, new_args); }); call->Destroy();
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc index ae7214a..c9cb1da 100644 --- a/src/tint/lang/spirv/reader/parser/parser.cc +++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -1781,6 +1781,9 @@ case spv::Op::OpImageSampleDrefImplicitLod: EmitImageSampleDepth(inst, spirv::BuiltinFn::kImageSampleDrefImplicitLod); break; + case spv::Op::OpImageSampleDrefExplicitLod: + EmitImageSampleDepth(inst, spirv::BuiltinFn::kImageSampleDrefExplicitLod); + break; case spv::Op::OpPhi: EmitPhi(inst); break;
diff --git a/src/tint/lang/spirv/reader/texture_test.cc b/src/tint/lang/spirv/reader/texture_test.cc index 24d69cc..c67109f 100644 --- a/src/tint/lang/spirv/reader/texture_test.cc +++ b/src/tint/lang/spirv/reader/texture_test.cc
@@ -1379,6 +1379,7 @@ %float_3 = OpConstant %float 3 %float_4 = OpConstant %float 4 %float_5 = OpConstant %float 5 +%float_null = OpConstantNull %float %coords2 = OpConstantComposite %v2float %float_1 %float_2 %coords3 = OpConstantComposite %v3float %float_1 %float_2 %float_3 %coords4 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4 @@ -1469,27 +1470,40 @@ %7:f32 = swizzle vec3<f32>(1.0f, 2.0f, 3.0f), z %8:i32 = convert %7 %9:f32 = textureSampleCompare %5, %4, %6, %8, 1.0f, vec2<i32>(10i, 11i))", + }, + ImgData{ + .name = "2D vec2 depth", + .spirv_type = "%float 2D 1 0 0 1 Unknown", + .spirv_fn = "OpImageSampleDrefImplicitLod %float %sampled_image %coords2 %float_1", + .wgsl_type = "texture_depth_2d", + .wgsl_fn = R"( + %6:f32 = textureSampleCompare %5, %4, vec2<f32>(1.0f, 2.0f), 1.0f)", })); INSTANTIATE_TEST_SUITE_P( - DISABLED_SpirvReaderTest_ImageSampleDrefExplicitLod, + SpirvReaderTest_ImageSampleDrefExplicitLod, SamplerComparisonTest, ::testing::Values( ImgData{ .name = "2D", .spirv_type = "%float 2D 1 0 0 1 Unknown", - .spirv_fn = "OpImageSampleDrefExplicitLod %float %sampled_image %coords2 " - "%depth Lod %float_0", + .spirv_fn = + "OpImageSampleDrefExplicitLod %float %sampled_image %coords2 %depth Lod %float_0", .wgsl_type = "texture_depth_2d", - .wgsl_fn = "textureSampleCompareLevel %4, %5, vec2<f32>(1.0f, 2.0f), 1.0f", + .wgsl_fn = R"( + %6:f32 = textureSampleCompareLevel %5, %4, vec2<f32>(1.0f, 2.0f), 1.0f)", }, ImgData{ .name = "2D array", .spirv_type = "%float 2D 1 1 0 1 Unknown", - .spirv_fn = "OpImageSampleDrefExplicitLod %float %sampled_image %coords3 " - "%depth Lod %float_0", + .spirv_fn = + "OpImageSampleDrefExplicitLod %float %sampled_image %coords3 %depth Lod %float_0", .wgsl_type = "texture_depth_2d_array", - .wgsl_fn = "textureSampleCompareLevel %4, %5, vec2<f32>(1.0f, 2.0f), 3i, 1.0f", + .wgsl_fn = R"( + %6:vec2<f32> = swizzle vec3<f32>(1.0f, 2.0f, 3.0f), xy + %7:f32 = swizzle vec3<f32>(1.0f, 2.0f, 3.0f), z + %8:i32 = convert %7 + %9:f32 = textureSampleCompareLevel %5, %4, %6, %8, 1.0f)", }, ImgData{ .name = "2D ConstOffset", @@ -1497,8 +1511,8 @@ .spirv_fn = "OpImageSampleDrefExplicitLod %float %sampled_image %coords2 %depth " "Lod|ConstOffset %float_0 %offset2i", .wgsl_type = "texture_depth_2d", - .wgsl_fn = "textureSampleCompareLevel %4, %5, vec2<f32>(1.0f, 2.0f), 1.0f, " - "vec2<i32>(10i, 11i)", + .wgsl_fn = R"( + %6:f32 = textureSampleCompareLevel %5, %4, vec2<f32>(1.0f, 2.0f), 1.0f, vec2<i32>(10i, 11i))", }, ImgData{ .name = "2D array ConstOffset", @@ -1506,26 +1520,44 @@ .spirv_fn = "OpImageSampleDrefExplicitLod %float %sampled_image %coords3 %depth " "Lod|ConstOffset %float_0 %offset2i", .wgsl_type = "texture_depth_2d_array", - .wgsl_fn = "textureSampleCompareLevel %4, %5, vec2<f32>(1.0f, 2.0f), 3i, 1.0f, " - "vec2<i32>(10i, 11i)", + .wgsl_fn = R"( + %6:vec2<f32> = swizzle vec3<f32>(1.0f, 2.0f, 3.0f), xy + %7:f32 = swizzle vec3<f32>(1.0f, 2.0f, 3.0f), z + %8:i32 = convert %7 + %9:f32 = textureSampleCompareLevel %5, %4, %6, %8, 1.0f, vec2<i32>(10i, 11i))", }, ImgData{ .name = "Cube", .spirv_type = "%float Cube 1 0 0 1 Unknown", - .spirv_fn = "OpImageSampleDrefExplicitLod %float %sampled_image %coords3 " - "%depth Lod %float_0", + .spirv_fn = + "OpImageSampleDrefExplicitLod %float %sampled_image %coords3 %depth Lod %float_0", .wgsl_type = "texture_depth_cube", - .wgsl_fn = "textureSampleCompareLevel %4, %5, vec3<f32>(1.0f, 2.0f, 3.0f), 1.0f", + .wgsl_fn = R"( + %6:f32 = textureSampleCompareLevel %5, %4, vec3<f32>(1.0f, 2.0f, 3.0f), 1.0f)", }, ImgData{ .name = "Cube array", .spirv_type = "%float Cube 1 1 0 1 Unknown", - .spirv_fn = "OpImageSampleDrefExplicitLod %float %sampled_image %coords4 " - "%depth Lod %float_0", + .spirv_fn = + "OpImageSampleDrefExplicitLod %float %sampled_image %coords4 %depth Lod %float_0", .wgsl_type = "texture_depth_cube_array", - .wgsl_fn = "textureSampleCompareLevel %4, %5, vec3<f32>(1.0f, 2.0f, 3.0f), " - "4i, 1.0f", - })); + .wgsl_fn = R"( + %6:vec3<f32> = swizzle vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f), xyz + %7:f32 = swizzle vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f), w + %8:i32 = convert %7 + %9:f32 = textureSampleCompareLevel %5, %4, %6, %8, 1.0f)", + }, + ImgData{ + .name = "2d vec2 depth lod", + .spirv_type = "%float 2D 1 0 0 1 Unknown", + .spirv_fn = + "OpImageSampleDrefExplicitLod %float %sampled_image %coords2 %float_1 Lod %float_0", + .wgsl_type = "texture_depth_2d", + .wgsl_fn = R"( + %6:f32 = textureSampleCompareLevel %5, %4, vec2<f32>(1.0f, 2.0f), 1.0f)", + } + + )); INSTANTIATE_TEST_SUITE_P( DISABLED_SpirvReaderTest_ImageSampleProjDrefImplicitLod, @@ -1570,6 +1602,34 @@ "vec2<i32>(10i, 11i)", })); +// Metal requires comparison sampling with explicit Level-of-detail to use Lod 0. The SPIR-V reader +// requires the operand to be parsed as a constant 0 value. SPIR-V validation requires the Lod +// parameter to be a floating point value for non-fetch operations. So only test float values. +INSTANTIATE_TEST_SUITE_P( + SpirvReaderTest_ImageSampleDrefExplicitLod_CheckForLod0, + SamplerComparisonTest, + ::testing::Values( + ImgData{ + .name = "2d 0.0", + .spirv_type = "%float 2D 1 0 0 1 Unknown", + .spirv_fn = + "OpImageSampleDrefExplicitLod %float %sampled_image %coords4 %float_1 Lod %float_0", + .wgsl_type = "texture_depth_2d", + .wgsl_fn = R"( + %6:vec2<f32> = swizzle vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f), xy + %7:f32 = textureSampleCompareLevel %5, %4, %6, 1.0f)", + }, + ImgData{ + .name = "2D null", + .spirv_type = "%float 2D 1 0 0 1 Unknown", + .spirv_fn = "OpImageSampleDrefExplicitLod %float %sampled_image %coords4 %float_1 Lod " + "%float_null", + .wgsl_type = "texture_depth_2d", + .wgsl_fn = R"( + %6:vec2<f32> = swizzle vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f), xy + %7:f32 = textureSampleCompareLevel %5, %4, %6, 1.0f)", + })); + // This test shows the use of a sampled image used with both regular // sampling and depth-reference sampling. The texture is a depth-texture, // and we use builtins textureSample and textureSampleCompare @@ -2900,7 +2960,7 @@ // In SPIR-V, sampling and dref sampling operations use floating point coordinates. Prove that we // preserve floating point-ness. Test across all such instructions. INSTANTIATE_TEST_SUITE_P( - DISABLED_SpirvReaderTest_PreserveFloatCoords_NonArrayed, + SpirvReaderTest_PreserveFloatCoords_NonArrayed, SampledImageCoordsTest, ::testing::Values( // Scalar cases @@ -2908,48 +2968,35 @@ .name = "1D", .spirv_type = "%float 1D 0 0 0 1 Unknown", .spirv_fn = "%result = OpImageSampleImplicitLod %v4float %sampled_image %float_1", - .wgsl_type = "", - .wgsl_fn = "f1", + .wgsl_type = "texture_1d<f32>", + .wgsl_fn = R"( + %6:vec4<f32> = textureSample %5, %4, 1.0f)", }, ImgData{ .name = "1D lod", .spirv_type = "%float 1D 0 0 0 1 Unknown", .spirv_fn = "%result = OpImageSampleExplicitLod %v4float %sampled_image %float_1 Lod %float_1", - .wgsl_type = "", - .wgsl_fn = "f1", + .wgsl_type = "texture_1d<f32>", + .wgsl_fn = R"( + %6:vec4<f32> = textureSampleLevel %5, %4, 1.0f, 1.0f)", }, ImgData{ .name = "2D vec2", .spirv_type = "%float 2D 0 0 0 1 Unknown", .spirv_fn = "%result = OpImageSampleImplicitLod %v4float %sampled_image %vf12", - .wgsl_type = "", - .wgsl_fn = "vf12", + .wgsl_type = "texture_2d<f32>", + .wgsl_fn = R"( + %6:vec4<f32> = textureSample %5, %4, vec2<f32>(1.0f, 2.0f))", }, ImgData{ .name = "2D vec2 lod", .spirv_type = "%float 2D 0 0 0 1 Unknown", .spirv_fn = "%result = OpImageSampleExplicitLod %v4float %sampled_image %vf12 Lod %float_1", - .wgsl_type = "", - .wgsl_fn = "vf12", - }, - ImgData{ - .name = "2D vec2 depth", - .spirv_type = "%float 2D 1 0 0 1 Unknown", - .spirv_fn = - "%result = OpImageSampleDrefImplicitLod %float %sampled_image %vf12 %float_1", - .wgsl_type = "", - .wgsl_fn = "vf12", - }, - ImgData{ - .name = "2d vec2 depth lod", - .spirv_type = "%float 2D 1 0 0 1 Unknown", - .spirv_fn = - "%result = OpImageSampleDrefExplicitLod %float %sampled_image %vf12 %float_1 " - "Lod %float_0", - .wgsl_type = "", - .wgsl_fn = "vf12", + .wgsl_type = "texture_2d<f32>", + .wgsl_fn = R"( + %6:vec4<f32> = textureSampleLevel %5, %4, vec2<f32>(1.0f, 2.0f), 1.0f)", })); // In SPIR-V, sampling and dref sampling operations use floating point coordinates. Prove that we @@ -2994,30 +3041,6 @@ .wgsl_fn = "vf123.xy", })); -// Metal requires comparison sampling with explicit Level-of-detail to use Lod 0. The SPIR-V reader -// requires the operand to be parsed as a constant 0 value. SPIR-V validation requires the Lod -// parameter to be a floating point value for non-fetch operations. So only test float values. -INSTANTIATE_TEST_SUITE_P( - DISABLED_SpirvReaderTest_ImageSampleDrefExplicitLod_CheckForLod0, - SampledImageCoordsTest, - ::testing::Values( - ImgData{ - .name = "2d 0.0", - .spirv_type = "%float 2D 1 0 0 1 Unknown", - .spirv_fn = "%result = OpImageSampleDrefExplicitLod %float %sampled_image " - "%vf1234 %float_1 Lod %float_0", - .wgsl_type = "", - .wgsl_fn = "vf1234.xy", - }, - ImgData{ - .name = "2D null", - .spirv_type = "%float 2D 1 0 0 1 Unknown", - .spirv_fn = "%result = OpImageSampleDrefExplicitLod %float %sampled_image " - "%vf1234 %float_1 Lod %float_null", - .wgsl_type = "", - .wgsl_fn = "vf1234.xy", - })); - // This is like the previous test, but for Projection sampling. // // Metal requires comparison sampling with explicit Level-of-detail to use Lod 0. The SPIR-V reader