mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-13 23:26:24 +00:00
Allow non-struct buffer store types
For SPIR-V, wrap non-struct types in structs in the AddSpirvBlockDecoration transform. For MSL, wrap runtime-sized arrays in structs in the ModuleScopeVarToEntryPointParam transform. Bug: tint:1372 Change-Id: Icced5d77b4538e816aa9fab57a634a9f4c52fdab Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76162 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -459,42 +459,6 @@ bool Resolver::ValidateGlobalVariable(const sem::Variable* var) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (var->StorageClass()) {
|
||||
case ast::StorageClass::kStorage: {
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
|
||||
// A variable in the storage storage class is a storage buffer variable.
|
||||
// Its store type must be a host-shareable structure type with block
|
||||
// attribute, satisfying the storage class constraints.
|
||||
|
||||
auto* str = var->Type()->UnwrapRef()->As<sem::Struct>();
|
||||
if (!str) {
|
||||
AddError(
|
||||
"variables declared in the <storage> storage class must be of a "
|
||||
"structure type",
|
||||
decl->source);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ast::StorageClass::kUniform: {
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
|
||||
// A variable in the uniform storage class is a uniform buffer variable.
|
||||
// Its store type must be a host-shareable structure type with block
|
||||
// attribute, satisfying the storage class constraints.
|
||||
auto* str = var->Type()->UnwrapRef()->As<sem::Struct>();
|
||||
if (!str) {
|
||||
AddError(
|
||||
"variables declared in the <uniform> storage class must be of a "
|
||||
"structure type",
|
||||
decl->source);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!decl->is_const) {
|
||||
if (!ValidateAtomicVariable(var)) {
|
||||
return false;
|
||||
@@ -580,14 +544,6 @@ bool Resolver::ValidateVariable(const sem::Variable* var) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto* r = storage_ty->As<sem::Array>()) {
|
||||
if (r->IsRuntimeSized()) {
|
||||
AddError("runtime arrays may only appear as the last member of a struct",
|
||||
decl->source);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* r = storage_ty->As<sem::MultisampledTexture>()) {
|
||||
if (r->dim() != ast::TextureDimension::k2d) {
|
||||
AddError("only 2d multisampled textures are supported", decl->source);
|
||||
|
||||
@@ -92,6 +92,40 @@ note: while analysing structure member S.m
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
|
||||
// var<storage> g : bool;
|
||||
Global(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kStorage,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(0),
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
ASSERT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
|
||||
56:78 note: while instantiating variable g)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) {
|
||||
// var<storage> g : ptr<private, f32>;
|
||||
Global(Source{{56, 78}}, "g",
|
||||
ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
|
||||
ast::StorageClass::kStorage,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(0),
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
ASSERT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in storage class 'storage' as it is non-host-shareable
|
||||
56:78 note: while instantiating variable g)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, StorageBufferIntScalar) {
|
||||
// var<storage> g : i32;
|
||||
Global(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kStorage,
|
||||
ast::DecorationList{
|
||||
@@ -99,14 +133,10 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
ASSERT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(56:78 error: variables declared in the <storage> storage class must be of a structure type)");
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) {
|
||||
TEST_F(ResolverStorageClassValidationTest, StorageBufferVector) {
|
||||
// var<storage> g : vec4<f32>;
|
||||
Global(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kStorage,
|
||||
ast::DecorationList{
|
||||
@@ -114,11 +144,7 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) {
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
ASSERT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(56:78 error: variables declared in the <storage> storage class must be of a structure type)");
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) {
|
||||
@@ -132,11 +158,7 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) {
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
ASSERT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(56:78 error: variables declared in the <storage> storage class must be of a structure type)");
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) {
|
||||
@@ -240,8 +262,10 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferBool) {
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, UniformBufferPointer) {
|
||||
// var<uniform> g : vec4<f32>;
|
||||
Global(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kUniform,
|
||||
// var<uniform> g : ptr<private, f32>;
|
||||
Global(Source{{56, 78}}, "g",
|
||||
ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
|
||||
ast::StorageClass::kUniform,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(0),
|
||||
create<ast::GroupDecoration>(0),
|
||||
@@ -251,7 +275,30 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferPointer) {
|
||||
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(56:78 error: variables declared in the <uniform> storage class must be of a structure type)");
|
||||
R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in storage class 'uniform' as it is non-host-shareable
|
||||
56:78 note: while instantiating variable g)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, UniformBufferIntScalar) {
|
||||
// var<uniform> g : i32;
|
||||
Global(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kUniform,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(0),
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, UniformBufferVector) {
|
||||
// var<uniform> g : vec4<f32>;
|
||||
Global(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kUniform,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(0),
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) {
|
||||
@@ -264,11 +311,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) {
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
ASSERT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(56:78 error: variables declared in the <uniform> storage class must be of a structure type)");
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassValidationTest, UniformBufferBoolAlias) {
|
||||
|
||||
Reference in New Issue
Block a user