Add validation rules for multisampled textures
Fixes:tint:717
Change-Id: I7f23086ec516c1196a9cdc741bbaa150754a533a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47940
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index dfcb456..ff7f50c 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -40,6 +40,7 @@
#include "src/sem/call.h"
#include "src/sem/function.h"
#include "src/sem/member_accessor_expression.h"
+#include "src/sem/multisampled_texture_type.h"
#include "src/sem/statement.h"
#include "src/sem/struct.h"
#include "src/sem/variable.h"
@@ -366,6 +367,23 @@
return false;
}
}
+
+ if (auto* mst = type->UnwrapAll()->As<sem::MultisampledTexture>()) {
+ if (mst->dim() != sem::TextureDimension::k2d) {
+ diagnostics_.add_error("Only 2d multisampled textures are supported",
+ var->source());
+ return false;
+ }
+
+ auto* data_type = mst->type()->UnwrapAll();
+ if (!data_type->is_numeric_scalar()) {
+ diagnostics_.add_error(
+ "texture_multisampled_2d<type>: type must be f32, i32 or u32",
+ var->source());
+ return false;
+ }
+ }
+
return true;
}
diff --git a/src/resolver/type_validation_test.cc b/src/resolver/type_validation_test.cc
index b8de796..48cf806 100644
--- a/src/resolver/type_validation_test.cc
+++ b/src/resolver/type_validation_test.cc
@@ -17,6 +17,7 @@
#include "src/ast/struct_block_decoration.h"
#include "src/resolver/resolver.h"
#include "src/resolver/resolver_test_helper.h"
+#include "src/sem/multisampled_texture_type.h"
#include "gmock/gmock.h"
@@ -532,6 +533,86 @@
} // namespace GetCanonicalTests
+namespace MultisampledTextureTests {
+struct DimensionParams {
+ sem::TextureDimension dim;
+ bool is_valid;
+};
+
+static constexpr DimensionParams dimension_cases[] = {
+ DimensionParams{sem::TextureDimension::k1d, false},
+ DimensionParams{sem::TextureDimension::k2d, true},
+ DimensionParams{sem::TextureDimension::k2dArray, false},
+ DimensionParams{sem::TextureDimension::k3d, false},
+ DimensionParams{sem::TextureDimension::kCube, false},
+ DimensionParams{sem::TextureDimension::kCubeArray, false}};
+
+using MultisampledTextureDimensionTest = ResolverTestWithParam<DimensionParams>;
+TEST_P(MultisampledTextureDimensionTest, All) {
+ auto& params = GetParam();
+ Global("a", create<sem::MultisampledTexture>(params.dim, ty.i32()),
+ ast::StorageClass::kUniformConstant, nullptr,
+ ast::DecorationList{
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
+
+ if (params.is_valid) {
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ } else {
+ EXPECT_FALSE(r()->Resolve());
+ }
+}
+INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
+ MultisampledTextureDimensionTest,
+ testing::ValuesIn(dimension_cases));
+
+struct TypeParams {
+ create_type_func_ptr type_func;
+ bool is_valid;
+};
+
+static constexpr TypeParams type_cases[] = {
+ TypeParams{ty_bool_, false},
+ TypeParams{ty_i32, true},
+ TypeParams{ty_u32, true},
+ TypeParams{ty_f32, true},
+
+ TypeParams{ty_alias<ty_bool_>, false},
+ TypeParams{ty_alias<ty_i32>, true},
+ TypeParams{ty_alias<ty_u32>, true},
+ TypeParams{ty_alias<ty_f32>, true},
+
+ TypeParams{ty_vec3<ty_f32>, false},
+ TypeParams{ty_mat3x3<ty_f32>, false},
+
+ TypeParams{ty_alias<ty_vec3<ty_f32>>, false},
+ TypeParams{ty_alias<ty_mat3x3<ty_f32>>, false}};
+
+using MultisampledTextureTypeTest = ResolverTestWithParam<TypeParams>;
+TEST_P(MultisampledTextureTypeTest, All) {
+ auto& params = GetParam();
+ Global("a",
+ create<sem::MultisampledTexture>(sem::TextureDimension::k2d,
+ params.type_func(ty)),
+ ast::StorageClass::kUniformConstant, nullptr,
+ ast::DecorationList{
+ create<ast::BindingDecoration>(0),
+ create<ast::GroupDecoration>(0),
+ });
+
+ if (params.is_valid) {
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ } else {
+ EXPECT_FALSE(r()->Resolve());
+ }
+}
+INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
+ MultisampledTextureTypeTest,
+ testing::ValuesIn(type_cases));
+
+} // namespace MultisampledTextureTests
+
} // namespace
} // namespace resolver
} // namespace tint
diff --git a/src/sem/type.cc b/src/sem/type.cc
index 537bec1..947b149 100644
--- a/src/sem/type.cc
+++ b/src/sem/type.cc
@@ -74,6 +74,10 @@
return IsAnyOf<F32, U32, I32, Bool>();
}
+bool Type::is_numeric_scalar() const {
+ return IsAnyOf<F32, U32, I32>();
+}
+
bool Type::is_float_scalar() const {
return Is<F32>();
}
diff --git a/src/sem/type.h b/src/sem/type.h
index 8a7137c..870bc16 100644
--- a/src/sem/type.h
+++ b/src/sem/type.h
@@ -69,6 +69,8 @@
/// @returns true if this type is a scalar
bool is_scalar() const;
+ /// @returns true if this type is a numeric scalar
+ bool is_numeric_scalar() const;
/// @returns true if this type is a float scalar
bool is_float_scalar() const;
/// @returns true if this type is a float matrix