[wgsl-writer] Generate builtin and location decorations on struct members

Bug: tint:576
Change-Id: Ie8ace8dd77095abedcca97caca330e2d11a7559c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/44321
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
James Price 2021-03-11 17:47:52 +00:00 committed by Commit Bot service account
parent 95d4077648
commit d3e3681d63
4 changed files with 47 additions and 19 deletions

View File

@ -500,14 +500,14 @@ bool GeneratorImpl::EmitStructType(const type::Struct* str) {
increment_indent();
for (auto* mem : impl->members()) {
for (auto* deco : mem->decorations()) {
if (!mem->decorations().empty()) {
make_indent();
// TODO(dsinclair): Split this out when we have more then one
auto* offset = deco->As<ast::StructMemberOffsetDecoration>();
assert(offset != nullptr);
out_ << "[[offset(" << offset->offset() << ")]]" << std::endl;
if (!EmitDecorations(mem->decorations())) {
return false;
}
out_ << std::endl;
}
make_indent();
out_ << program_->Symbols().NameFor(mem->symbol()) << " : ";
if (!EmitType(mem->type())) {
@ -527,9 +527,12 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var) {
make_indent();
if (!var->decorations().empty() && !EmitVariableDecorations(sem)) {
if (!var->decorations().empty()) {
if (!EmitDecorations(var->decorations())) {
return false;
}
out_ << " ";
}
if (var->is_const()) {
out_ << "const";
@ -558,12 +561,10 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var) {
return true;
}
bool GeneratorImpl::EmitVariableDecorations(const semantic::Variable* var) {
auto* decl = var->Declaration();
bool GeneratorImpl::EmitDecorations(const ast::DecorationList& decos) {
out_ << "[[";
bool first = true;
for (auto* deco : decl->decorations()) {
for (auto* deco : decos) {
if (!first) {
out_ << ", ";
}
@ -579,12 +580,14 @@ bool GeneratorImpl::EmitVariableDecorations(const semantic::Variable* var) {
out_ << "builtin(" << builtin->value() << ")";
} else if (auto* constant = deco->As<ast::ConstantIdDecoration>()) {
out_ << "constant_id(" << constant->value() << ")";
} else if (auto* offset = deco->As<ast::StructMemberOffsetDecoration>()) {
out_ << "offset(" << offset->offset() << ")";
} else {
diagnostics_.add_error("unknown variable decoration");
return false;
}
}
out_ << "]] ";
out_ << "]]";
return true;
}

View File

@ -193,10 +193,10 @@ class GeneratorImpl : public TextGenerator {
/// @param var the variable to generate
/// @returns true if the variable was emitted
bool EmitVariable(ast::Variable* var);
/// Handles generating variable decorations
/// @param var the decorated variable
/// @returns true if the variable decoration was emitted
bool EmitVariableDecorations(const semantic::Variable* var);
/// Handles generating a decoration list
/// @param decos the decoration list
/// @returns true if the decorations were emitted
bool EmitDecorations(const ast::DecorationList& decos);
private:
Program const* const program_;

View File

@ -53,10 +53,10 @@ TEST_P(WgslBuiltinConversionTest, Emit) {
GeneratorImpl& gen = Build();
gen.EmitVariableDecorations(program->Sem().Get(var));
gen.EmitDecorations(var->decorations());
EXPECT_EQ(gen.result(),
"[[builtin(" + std::string(params.attribute_name) + ")]] ");
"[[builtin(" + std::string(params.attribute_name) + ")]]");
}
INSTANTIATE_TEST_SUITE_P(
WgslGeneratorImplTest,

View File

@ -210,6 +210,31 @@ struct S {
)");
}
TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithEntryPointDecorations) {
ast::DecorationList decos;
decos.push_back(create<ast::StructBlockDecoration>());
auto* str = create<ast::Struct>(
ast::StructMemberList{
Member("a", ty.u32(),
{create<ast::BuiltinDecoration>(ast::Builtin::kVertexIndex)}),
Member("b", ty.f32(), {create<ast::LocationDecoration>(2u)})},
decos);
auto* s = ty.struct_("S", str);
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
EXPECT_EQ(gen.result(), R"([[block]]
struct S {
[[builtin(vertex_index)]]
a : u32;
[[location(2)]]
b : f32;
};
)");
}
TEST_F(WgslGeneratorImplTest, EmitType_U32) {
auto* u32 = ty.u32();