writer/hlsl: Don't emit structs for storage buffer usage
Use the semantic StorageClassUsage() to determine whether the structure is used only for storage buffer usage. If it is, don't emit a struct definition for it.
This fixes issues with attempting to generate runtime arrays - they're only legal for storage buffer usage. Storage buffers use ByteAddressBuffer instead of structured loads / stores.
Bug: tint:185
Fixed: tint:682
Change-Id: I5b58a133eee2fe036a84e028fa85b611e4895b1a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/46382
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index f7a7e96..bd5a00c 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -2590,9 +2590,17 @@
bool GeneratorImpl::EmitStructType(std::ostream& out,
const type::Struct* str,
const std::string& name) {
- // TODO(dsinclair): Block decoration?
- // if (str->impl()->decoration() != ast::Decoration::kNone) {
- // }
+ auto* sem_str = builder_.Sem().Get(str);
+
+ auto storage_class_uses = sem_str->StorageClassUsage();
+ if (storage_class_uses.size() ==
+ storage_class_uses.count(ast::StorageClass::kStorage)) {
+ // The only use of the structure is as a storage buffer.
+ // Structures used as storage buffer are read and written to via a
+ // ByteAddressBuffer instead of true structure.
+ return true;
+ }
+
out << "struct " << name << " {" << std::endl;
increment_indent();
diff --git a/src/writer/hlsl/generator_impl_alias_type_test.cc b/src/writer/hlsl/generator_impl_alias_type_test.cc
index ca1007b..8a24701 100644
--- a/src/writer/hlsl/generator_impl_alias_type_test.cc
+++ b/src/writer/hlsl/generator_impl_alias_type_test.cc
@@ -42,15 +42,13 @@
}
TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_Struct) {
- auto* str = create<ast::Struct>(
- ast::StructMemberList{
- Member("a", ty.f32()),
- Member("b", ty.i32()),
- },
- ast::DecorationList{});
-
- auto* s = ty.struct_("A", str);
+ auto* s = Structure("A", {
+ Member("a", ty.f32()),
+ Member("b", ty.i32()),
+ });
auto* alias = ty.alias("B", s);
+ AST().AddConstructedType(alias);
+ Global("g", alias, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
diff --git a/src/writer/hlsl/generator_impl_function_test.cc b/src/writer/hlsl/generator_impl_function_test.cc
index cc4da75..35dadb9 100644
--- a/src/writer/hlsl/generator_impl_function_test.cc
+++ b/src/writer/hlsl/generator_impl_function_test.cc
@@ -916,10 +916,7 @@
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate(out)) << gen.error();
- EXPECT_EQ(result(), R"(struct Data {
- float d;
-};
-
+ EXPECT_EQ(result(), R"(
RWByteAddressBuffer data : register(u0, space0);
[numthreads(1, 1, 1)]
diff --git a/src/writer/hlsl/generator_impl_type_test.cc b/src/writer/hlsl/generator_impl_type_test.cc
index 5353b5c..5f6f63c 100644
--- a/src/writer/hlsl/generator_impl_type_test.cc
+++ b/src/writer/hlsl/generator_impl_type_test.cc
@@ -171,6 +171,7 @@
Member("a", ty.i32()),
Member("b", ty.f32()),
});
+ Global("g", s, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -182,11 +183,25 @@
)");
}
+TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl_OmittedIfStorageBuffer) {
+ auto* s = Structure("S", {
+ Member("a", ty.i32()),
+ Member("b", ty.f32()),
+ });
+ Global("g", s, ast::StorageClass::kStorage);
+
+ GeneratorImpl& gen = Build();
+
+ ASSERT_TRUE(gen.EmitStructType(out, s, "S")) << gen.error();
+ EXPECT_EQ(result(), "");
+}
+
TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) {
auto* s = Structure("S", {
Member("a", ty.i32()),
Member("b", ty.f32()),
});
+ Global("g", s, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -203,6 +218,7 @@
Member("b", ty.f32()),
Member("c", ty.f32(), {MemberAlign(128), MemberSize(128)}),
});
+ Global("g", s, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -223,6 +239,7 @@
Member("double", ty.i32()),
Member("float", ty.f32()),
});
+ Global("g", s, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@@ -242,6 +259,7 @@
Member("b", ty.f32()),
},
{create<ast::StructBlockDecoration>()});
+ Global("g", s, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();