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>
This commit is contained in:
Ben Clayton 2021-03-30 20:18:28 +00:00 committed by Commit Bot service account
parent 96a57f65dd
commit 0f02a6de00
4 changed files with 36 additions and 15 deletions

View File

@ -2590,9 +2590,17 @@ bool GeneratorImpl::EmitType(std::ostream& out,
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();

View File

@ -42,15 +42,13 @@ TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_NameCollision) {
}
TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_Struct) {
auto* str = create<ast::Struct>(
ast::StructMemberList{
auto* s = Structure("A", {
Member("a", ty.f32()),
Member("b", ty.i32()),
},
ast::DecorationList{});
auto* s = ty.struct_("A", str);
});
auto* alias = ty.alias("B", s);
AST().AddConstructedType(alias);
Global("g", alias, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();

View File

@ -916,10 +916,7 @@ TEST_F(HlslGeneratorImplTest_Function,
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)]

View File

@ -171,6 +171,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) {
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) {
)");
}
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 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_InjectPadding) {
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 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) {
Member("double", ty.i32()),
Member("float", ty.f32()),
});
Global("g", s, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();
@ -242,6 +259,7 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_WithDecoration) {
Member("b", ty.f32()),
},
{create<ast::StructBlockDecoration>()});
Global("g", s, ast::StorageClass::kPrivate);
GeneratorImpl& gen = Build();