spirv-reader: reject sampling operations on non-float textures
Fixed: tint:350
Bug: tint:109
Change-Id: I754ff4ade03dabb70a1eb5706a65c48a0a7d35a8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35581
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 386fdf1..82d9ec5 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -4080,6 +4080,13 @@
// or vice versa. Perform a bitcast.
value = create<ast::BitcastExpression>(Source{}, result_type, call_expr);
}
+ if (!expected_component_type->Is<ast::type::F32>() &&
+ IsSampledImageAccess(inst.opcode())) {
+ // WGSL permits sampled image access only on float textures.
+ // Reject this case in the SPIR-V reader, at least until SPIR-V validation
+ // catches up with this rule and can reject it earlier in the workflow.
+ return Fail() << "sampled image must have float component type";
+ }
EmitConstDefOrWriteToHoistedVar(inst, {result_type, value});
} else {
diff --git a/src/reader/spirv/parser_impl_handle_test.cc b/src/reader/spirv/parser_impl_handle_test.cc
index e0ee403..83055a6 100644
--- a/src/reader/spirv/parser_impl_handle_test.cc
+++ b/src/reader/spirv/parser_impl_handle_test.cc
@@ -3549,7 +3549,9 @@
//
// Sampling operations, using OpImageSampleImplicitLod as an example.
- //
+ // WGSL sampling operations only work on textures with a float sampled
+ // component. So we can only test the float -> float (non-conversion)
+ // case.
// OpImageSampleImplicitLod requires no conversion, float -> v4float
{"%float 2D 0 0 0 1 Unknown",
@@ -3589,156 +3591,6 @@
}
}
}
- })"},
- // OpImageSampleImplicitLod requires no conversion, uint -> v4uint
- {"%uint 2D 0 0 0 1 Unknown",
- "%99 = OpImageSampleImplicitLod %v4uint %sampled_image %vf12",
- R"(
- Variable{
- Decorations{
- SetDecoration{0}
- BindingDecoration{0}
- }
- x_10
- uniform_constant
- __sampler_sampler
- }
- Variable{
- Decorations{
- SetDecoration{2}
- BindingDecoration{1}
- }
- x_20
- uniform_constant
- __sampled_texture_2d__u32
- })",
- R"(VariableDeclStatement{
- VariableConst{
- x_99
- none
- __vec_4__u32
- {
- Call[not set]{
- Identifier[not set]{textureSample}
- (
- Identifier[not set]{x_20}
- Identifier[not set]{x_10}
- Identifier[not set]{vf12}
- )
- }
- }
- }
- })"},
- // OpImageSampleImplicitLod requires conversion, uint -> v4int
- {"%uint 2D 0 0 0 1 Unknown",
- "%99 = OpImageSampleImplicitLod %v4int %sampled_image %vf12",
- R"(
- Variable{
- Decorations{
- SetDecoration{0}
- BindingDecoration{0}
- }
- x_10
- uniform_constant
- __sampler_sampler
- }
- Variable{
- Decorations{
- SetDecoration{2}
- BindingDecoration{1}
- }
- x_20
- uniform_constant
- __sampled_texture_2d__u32
- })",
- R"(VariableDeclStatement{
- VariableConst{
- x_99
- none
- __vec_4__i32
- {
- Bitcast[not set]<__vec_4__i32>{
- Call[not set]{
- Identifier[not set]{textureSample}
- (
- Identifier[not set]{x_20}
- Identifier[not set]{x_10}
- Identifier[not set]{vf12}
- )
- }
- }
- }
- }
- })"},
- // OpImageSampleImplicitLod requires no conversion, int -> v4int
- {"%int 2D 0 0 0 1 Unknown",
- "%99 = OpImageSampleImplicitLod %v4int %sampled_image %vf12",
- R"(
- Variable{
- Decorations{
- SetDecoration{0}
- BindingDecoration{0}
- }
- x_10
- uniform_constant
- __sampler_sampler
- }
- Variable{
- Decorations{
- SetDecoration{2}
- BindingDecoration{1}
- }
- x_20
- uniform_constant
- __sampled_texture_2d__i32
- })",
- R"(VariableDeclStatement{
- VariableConst{
- x_99
- none
- __vec_4__i32
- {
- Call[not set]{
- Identifier[not set]{textureSample}
- (
- Identifier[not set]{x_20}
- Identifier[not set]{x_10}
- Identifier[not set]{vf12}
- )
- }
- }
- }
- })"},
- // OpImageSampleImplicitLod requires conversion, int -> v4uint
- {"%int 2D 0 0 0 1 Unknown",
- "%99 = OpImageSampleImplicitLod %v4uint %sampled_image %vf12",
- R"(Variable{
- Decorations{
- SetDecoration{2}
- BindingDecoration{1}
- }
- x_20
- uniform_constant
- __sampled_texture_2d__i32
- })",
- R"(VariableDeclStatement{
- VariableConst{
- x_99
- none
- __vec_4__u32
- {
- Bitcast[not set]<__vec_4__u32>{
- Call[not set]{
- Identifier[not set]{textureSample}
- (
- Identifier[not set]{x_20}
- Identifier[not set]{x_10}
- Identifier[not set]{vf12}
- )
- }
- }
- }
- }
})"}}));
struct ImageCoordsCase {
@@ -3837,7 +3689,7 @@
)";
auto p = parser(test::Assemble(assembly));
if (!p->BuildAndParseInternalModule()) {
- EXPECT_THAT(p->error(), Eq(GetParam().expected_error));
+ EXPECT_THAT(p->error(), Eq(GetParam().expected_error)) << assembly;
} else {
EXPECT_TRUE(p->error().empty()) << p->error();
FunctionEmitter fe(p.get(), *spirv_function(p.get(), 100));
@@ -4486,6 +4338,53 @@
{}},
}));
+INSTANTIATE_TEST_SUITE_P(
+ SampleNonFloatTexture_IsError,
+ SpvParserTest_ImageCoordsTest,
+ ::testing::ValuesIn(std::vector<ImageCoordsCase>{
+ // ImageSampleImplicitLod
+ {"%uint 2D 0 0 0 1 Unknown",
+ "%result = OpImageSampleImplicitLod %v4uint %sampled_image %vf12",
+ "sampled image must have float component type",
+ {}},
+ {"%int 2D 0 0 0 1 Unknown",
+ "%result = OpImageSampleImplicitLod %v4int %sampled_image %vf12",
+ "sampled image must have float component type",
+ {}},
+ // ImageSampleExplicitLod
+ {"%uint 2D 0 0 0 1 Unknown",
+ "%result = OpImageSampleExplicitLod %v4uint %sampled_image %vf12 "
+ "Lod %f1",
+ "sampled image must have float component type",
+ {}},
+ {"%int 2D 0 0 0 1 Unknown",
+ "%result = OpImageSampleExplicitLod %v4int %sampled_image %vf12 "
+ "Lod %f1",
+ "sampled image must have float component type",
+ {}},
+ // ImageSampleDrefImplicitLod
+ {"%uint 2D 0 0 0 1 Unknown",
+ "%result = OpImageSampleDrefImplicitLod %v4uint %sampled_image %vf12 "
+ "%f1",
+ "sampled image must have float component type",
+ {}},
+ {"%int 2D 0 0 0 1 Unknown",
+ "%result = OpImageSampleDrefImplicitLod %v4int %sampled_image %vf12 "
+ "%f1",
+ "sampled image must have float component type",
+ {}},
+ // ImageSampleDrefExplicitLod
+ {"%uint 2D 0 0 0 1 Unknown",
+ "%result = OpImageSampleDrefExplicitLod %v4uint %sampled_image %vf12 "
+ "%f1 Lod %f1",
+ "sampled image must have float component type",
+ {}},
+ {"%int 2D 0 0 0 1 Unknown",
+ "%result = OpImageSampleDrefExplicitLod %v4int %sampled_image %vf12 "
+ "%f1 Lod %f1",
+ "sampled image must have float component type",
+ {}}}));
+
} // namespace
} // namespace spirv
} // namespace reader