Update structs to allow multiple decorations
This CL updates to match the spec change allowing multiple struct decorations. Bug: tint:240 Change-Id: Id859c6a331c67c46597fc3c70de06d6cc0f486ec Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/29260 Commit-Queue: dan sinclair <dsinclair@chromium.org> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
007dc42cbb
commit
1a63c49b4e
|
@ -19,13 +19,19 @@ namespace ast {
|
|||
|
||||
Struct::Struct() : Node() {}
|
||||
|
||||
Struct::Struct(StructDecoration decoration, StructMemberList members)
|
||||
: Node(), decoration_(decoration), members_(std::move(members)) {}
|
||||
Struct::Struct(StructMemberList members)
|
||||
: Node(), members_(std::move(members)) {}
|
||||
|
||||
Struct::Struct(StructDecorationList decorations, StructMemberList members)
|
||||
: Node(), decorations_(decorations), members_(std::move(members)) {}
|
||||
|
||||
Struct::Struct(const Source& source, StructMemberList members)
|
||||
: Node(source), members_(std::move(members)) {}
|
||||
|
||||
Struct::Struct(const Source& source,
|
||||
StructDecoration decoration,
|
||||
StructDecorationList decorations,
|
||||
StructMemberList members)
|
||||
: Node(source), decoration_(decoration), members_(std::move(members)) {}
|
||||
: Node(source), decorations_(decorations), members_(std::move(members)) {}
|
||||
|
||||
Struct::Struct(Struct&&) = default;
|
||||
|
||||
|
@ -40,7 +46,21 @@ StructMember* Struct::get_member(const std::string& name) const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool Struct::IsBlockDecorated() const {
|
||||
for (auto deco : decorations_) {
|
||||
if (deco == StructDecoration::kBlock) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Struct::IsValid() const {
|
||||
for (auto deco : decorations_) {
|
||||
if (deco == StructDecoration::kNone) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (const auto& mem : members_) {
|
||||
if (mem == nullptr || !mem->IsValid()) {
|
||||
return false;
|
||||
|
@ -51,10 +71,11 @@ bool Struct::IsValid() const {
|
|||
|
||||
void Struct::to_str(std::ostream& out, size_t indent) const {
|
||||
make_indent(out, indent);
|
||||
if (decoration_ != StructDecoration::kNone) {
|
||||
out << "[[" << decoration_ << "]] ";
|
||||
}
|
||||
out << "Struct{" << std::endl;
|
||||
for (auto deco : decorations_) {
|
||||
make_indent(out, indent + 2);
|
||||
out << "[[" << deco << "]]" << std::endl;
|
||||
}
|
||||
for (const auto& member : members_) {
|
||||
member->to_str(out, indent + 2);
|
||||
}
|
||||
|
|
|
@ -32,15 +32,22 @@ class Struct : public Node {
|
|||
/// Create a new empty struct statement
|
||||
Struct();
|
||||
/// Create a new struct statement
|
||||
/// @param decoration The struct decorations
|
||||
/// @param members The struct members
|
||||
Struct(StructDecoration decoration, StructMemberList members);
|
||||
explicit Struct(StructMemberList members);
|
||||
/// Create a new struct statement
|
||||
/// @param decorations The struct decorations
|
||||
/// @param members The struct members
|
||||
Struct(StructDecorationList decorations, StructMemberList members);
|
||||
/// Create a new struct statement
|
||||
/// @param source The input source for the import statement
|
||||
/// @param decoration The struct decorations
|
||||
/// @param members The struct members
|
||||
Struct(const Source& source, StructMemberList members);
|
||||
/// Create a new struct statement
|
||||
/// @param source The input source for the import statement
|
||||
/// @param decorations The struct decorations
|
||||
/// @param members The struct members
|
||||
Struct(const Source& source,
|
||||
StructDecoration decoration,
|
||||
StructDecorationList decorations,
|
||||
StructMemberList members);
|
||||
/// Move constructor
|
||||
Struct(Struct&&);
|
||||
|
@ -48,10 +55,12 @@ class Struct : public Node {
|
|||
~Struct() override;
|
||||
|
||||
/// Sets the struct decoration
|
||||
/// @param deco the decoration to set
|
||||
void set_decoration(StructDecoration deco) { decoration_ = deco; }
|
||||
/// @returns the struct decoration
|
||||
StructDecoration decoration() const { return decoration_; }
|
||||
/// @param decos the list of decorations to set
|
||||
void set_decorations(StructDecorationList decos) {
|
||||
decorations_ = std::move(decos);
|
||||
}
|
||||
/// @returns the struct decorations
|
||||
const StructDecorationList& decorations() const { return decorations_; }
|
||||
|
||||
/// Sets the struct members
|
||||
/// @param members the members to set
|
||||
|
@ -64,6 +73,9 @@ class Struct : public Node {
|
|||
/// @returns the struct member or nullptr if not found
|
||||
StructMember* get_member(const std::string& name) const;
|
||||
|
||||
/// @returns true if the struct is block decorated
|
||||
bool IsBlockDecorated() const;
|
||||
|
||||
/// @returns true if the node is valid
|
||||
bool IsValid() const override;
|
||||
|
||||
|
@ -75,7 +87,7 @@ class Struct : public Node {
|
|||
private:
|
||||
Struct(const Struct&) = delete;
|
||||
|
||||
StructDecoration decoration_ = StructDecoration::kNone;
|
||||
StructDecorationList decorations_;
|
||||
StructMemberList members_;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@ enum class StructDecoration { kNone = -1, kBlock };
|
|||
|
||||
std::ostream& operator<<(std::ostream& out, StructDecoration stage);
|
||||
|
||||
/// List of struct decorations
|
||||
using StructDecorationList = std::vector<StructDecoration>;
|
||||
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
||||
|
|
|
@ -35,23 +35,45 @@ TEST_F(StructTest, Creation) {
|
|||
members.push_back(
|
||||
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
|
||||
|
||||
Struct s{StructDecoration::kNone, std::move(members)};
|
||||
Struct s{std::move(members)};
|
||||
EXPECT_EQ(s.members().size(), 1u);
|
||||
EXPECT_EQ(s.decoration(), StructDecoration::kNone);
|
||||
EXPECT_TRUE(s.decorations().empty());
|
||||
EXPECT_EQ(s.line(), 0u);
|
||||
EXPECT_EQ(s.column(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(StructTest, CreationWithSource) {
|
||||
TEST_F(StructTest, Creation_WithDecorations) {
|
||||
type::I32Type i32;
|
||||
Source source{27, 4};
|
||||
|
||||
StructMemberList members;
|
||||
members.push_back(
|
||||
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
|
||||
|
||||
StructDecorationList decos;
|
||||
decos.push_back(StructDecoration::kBlock);
|
||||
|
||||
Struct s{std::move(decos), std::move(members)};
|
||||
EXPECT_EQ(s.members().size(), 1u);
|
||||
ASSERT_EQ(s.decorations().size(), 1u);
|
||||
EXPECT_EQ(s.decorations()[0], StructDecoration::kBlock);
|
||||
EXPECT_EQ(s.line(), 0u);
|
||||
EXPECT_EQ(s.column(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(StructTest, CreationWithSourceAndDecorations) {
|
||||
type::I32Type i32;
|
||||
|
||||
StructMemberList members;
|
||||
members.emplace_back(
|
||||
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
|
||||
|
||||
Struct s{source, StructDecoration::kNone, std::move(members)};
|
||||
StructDecorationList decos;
|
||||
decos.push_back(StructDecoration::kBlock);
|
||||
|
||||
Struct s{Source{27, 4}, std::move(decos), std::move(members)};
|
||||
EXPECT_EQ(s.members().size(), 1u);
|
||||
EXPECT_EQ(s.decoration(), StructDecoration::kNone);
|
||||
ASSERT_EQ(s.decorations().size(), 1u);
|
||||
EXPECT_EQ(s.decorations()[0], StructDecoration::kBlock);
|
||||
EXPECT_EQ(s.line(), 27u);
|
||||
EXPECT_EQ(s.column(), 4u);
|
||||
}
|
||||
|
@ -63,37 +85,57 @@ TEST_F(StructTest, IsValid) {
|
|||
|
||||
TEST_F(StructTest, IsValid_Null_StructMember) {
|
||||
type::I32Type i32;
|
||||
|
||||
StructMemberList members;
|
||||
members.push_back(
|
||||
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
|
||||
members.push_back(nullptr);
|
||||
|
||||
Struct s{StructDecoration::kNone, std::move(members)};
|
||||
Struct s{std::move(members)};
|
||||
EXPECT_FALSE(s.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(StructTest, IsValid_Invalid_StructMember) {
|
||||
type::I32Type i32;
|
||||
|
||||
StructMemberList members;
|
||||
members.push_back(
|
||||
std::make_unique<StructMember>("", &i32, StructMemberDecorationList()));
|
||||
|
||||
Struct s{StructDecoration::kNone, std::move(members)};
|
||||
Struct s{std::move(members)};
|
||||
EXPECT_FALSE(s.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(StructTest, IsValid_NoneDecoration) {
|
||||
type::I32Type i32;
|
||||
|
||||
StructMemberList members;
|
||||
members.push_back(
|
||||
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
|
||||
|
||||
StructDecorationList decos;
|
||||
decos.push_back(StructDecoration::kNone);
|
||||
|
||||
Struct s{std::move(decos), std::move(members)};
|
||||
EXPECT_FALSE(s.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(StructTest, ToStr) {
|
||||
type::I32Type i32;
|
||||
Source source{27, 4};
|
||||
|
||||
StructMemberList members;
|
||||
members.emplace_back(
|
||||
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
|
||||
|
||||
Struct s{source, StructDecoration::kNone, std::move(members)};
|
||||
StructDecorationList decos;
|
||||
decos.push_back(StructDecoration::kBlock);
|
||||
|
||||
Struct s{std::move(decos), std::move(members)};
|
||||
|
||||
std::ostringstream out;
|
||||
s.to_str(out, 2);
|
||||
EXPECT_EQ(out.str(), R"( Struct{
|
||||
[[block]]
|
||||
StructMember{a: __i32}
|
||||
}
|
||||
)");
|
||||
|
|
|
@ -42,9 +42,7 @@ class StructType : public Type {
|
|||
const std::string& name() const { return name_; }
|
||||
|
||||
/// @returns true if the struct has a block decoration
|
||||
bool IsBlockDecorated() const {
|
||||
return struct_->decoration() == StructDecoration::kBlock;
|
||||
}
|
||||
bool IsBlockDecorated() const { return struct_->IsBlockDecorated(); }
|
||||
|
||||
/// @returns true if the type is a struct type
|
||||
bool IsStruct() const override;
|
||||
|
|
|
@ -806,7 +806,8 @@ TEST_F(SpvParserTest, RemapStorageBuffer_TypesAndVarDeclarations) {
|
|||
}
|
||||
RTArr -> __array__u32_stride_4
|
||||
S -> __struct_S
|
||||
[[block]] Struct{
|
||||
Struct{
|
||||
[[block]]
|
||||
StructMember{[[ offset 0 ]] field0: __u32}
|
||||
StructMember{[[ offset 4 ]] field1: __alias_RTArr__array__u32_stride_4}
|
||||
})"));
|
||||
|
|
|
@ -789,13 +789,13 @@ ast::type::Type* ParserImpl::ConvertType(
|
|||
const spvtools::opt::analysis::Struct* struct_ty) {
|
||||
// Compute the struct decoration.
|
||||
auto struct_decorations = this->GetDecorationsFor(type_id);
|
||||
auto ast_struct_decoration = ast::StructDecoration::kNone;
|
||||
ast::StructDecorationList ast_struct_decorations;
|
||||
if (struct_decorations.size() == 1) {
|
||||
const auto decoration = struct_decorations[0][0];
|
||||
if (decoration == SpvDecorationBlock) {
|
||||
ast_struct_decoration = ast::StructDecoration::kBlock;
|
||||
ast_struct_decorations.push_back(ast::StructDecoration::kBlock);
|
||||
} else if (decoration == SpvDecorationBufferBlock) {
|
||||
ast_struct_decoration = ast::StructDecoration::kBlock;
|
||||
ast_struct_decorations.push_back(ast::StructDecoration::kBlock);
|
||||
remap_buffer_block_type_.insert(type_id);
|
||||
} else {
|
||||
Fail() << "struct with ID " << type_id
|
||||
|
@ -859,8 +859,8 @@ ast::type::Type* ParserImpl::ConvertType(
|
|||
}
|
||||
|
||||
// Now make the struct.
|
||||
auto ast_struct = std::make_unique<ast::Struct>(ast_struct_decoration,
|
||||
std::move(ast_members));
|
||||
auto ast_struct = std::make_unique<ast::Struct>(
|
||||
std::move(ast_struct_decorations), std::move(ast_members));
|
||||
// The struct type will be assigned a name during EmitAliasTypes.
|
||||
auto ast_struct_type =
|
||||
std::make_unique<ast::type::StructType>(std::move(ast_struct));
|
||||
|
|
|
@ -582,7 +582,8 @@ TEST_F(SpvParserTest, ConvertType_StructWithBlockDecoration) {
|
|||
EXPECT_TRUE(type->IsStruct());
|
||||
std::stringstream ss;
|
||||
type->AsStruct()->impl()->to_str(ss, 0);
|
||||
EXPECT_THAT(ss.str(), Eq(R"([[block]] Struct{
|
||||
EXPECT_THAT(ss.str(), Eq(R"(Struct{
|
||||
[[block]]
|
||||
StructMember{field0: __u32}
|
||||
}
|
||||
)"));
|
||||
|
|
|
@ -1311,7 +1311,8 @@ TEST_F(SpvParserTest, ModuleScopeVar_NonReadableDecoration_DroppedForNow) {
|
|||
__alias_S__struct_S
|
||||
}
|
||||
S -> __struct_S
|
||||
[[block]] Struct{
|
||||
Struct{
|
||||
[[block]]
|
||||
StructMember{field0: __u32}
|
||||
StructMember{field1: __f32}
|
||||
StructMember{field2: __array__u32_2}
|
||||
|
@ -1338,7 +1339,8 @@ TEST_F(SpvParserTest, ModuleScopeVar_NonWritableDecoration_DroppedForNow) {
|
|||
__alias_S__struct_S
|
||||
}
|
||||
S -> __struct_S
|
||||
[[block]] Struct{
|
||||
Struct{
|
||||
[[block]]
|
||||
StructMember{field0: __u32}
|
||||
StructMember{field1: __f32}
|
||||
StructMember{field2: __array__u32_2}
|
||||
|
@ -1369,7 +1371,8 @@ TEST_F(SpvParserTest, ModuleScopeVar_ColMajorDecoration_Dropped) {
|
|||
__alias_S__struct_S
|
||||
}
|
||||
S -> __struct_S
|
||||
[[block]] Struct{
|
||||
Struct{
|
||||
[[block]]
|
||||
StructMember{field0: __mat_2_3__f32}
|
||||
}
|
||||
})")) << module_str;
|
||||
|
@ -1398,7 +1401,8 @@ TEST_F(SpvParserTest, ModuleScopeVar_MatrixStrideDecoration_Dropped) {
|
|||
__alias_S__struct_S
|
||||
}
|
||||
S -> __struct_S
|
||||
[[block]] Struct{
|
||||
Struct{
|
||||
[[block]]
|
||||
StructMember{field0: __mat_2_3__f32}
|
||||
}
|
||||
})")) << module_str;
|
||||
|
|
|
@ -1445,14 +1445,21 @@ ast::StorageClass ParserImpl::storage_class() {
|
|||
}
|
||||
|
||||
// struct_decl
|
||||
// : struct_decoration_decl? STRUCT struct_body_decl
|
||||
// : struct_decoration_decl* STRUCT struct_body_decl
|
||||
std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl() {
|
||||
auto t = peek();
|
||||
auto source = t.source();
|
||||
|
||||
auto deco = struct_decoration_decl();
|
||||
if (has_error())
|
||||
return nullptr;
|
||||
ast::StructDecorationList decos;
|
||||
for (;;) {
|
||||
size_t s = decos.size();
|
||||
if (!struct_decoration_decl(decos)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (decos.size() == s) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
t = next();
|
||||
if (!t.IsStruct()) {
|
||||
|
@ -1466,22 +1473,25 @@ std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl() {
|
|||
}
|
||||
|
||||
return std::make_unique<ast::type::StructType>(
|
||||
std::make_unique<ast::Struct>(source, deco, std::move(body)));
|
||||
std::make_unique<ast::Struct>(source, std::move(decos), std::move(body)));
|
||||
}
|
||||
|
||||
// struct_decoration_decl
|
||||
// : ATTR_LEFT struct_decoration ATTR_RIGHT
|
||||
ast::StructDecoration ParserImpl::struct_decoration_decl() {
|
||||
bool ParserImpl::struct_decoration_decl(ast::StructDecorationList& decos) {
|
||||
auto t = peek();
|
||||
if (!t.IsAttrLeft())
|
||||
return ast::StructDecoration::kNone;
|
||||
if (!t.IsAttrLeft()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto deco = struct_decoration(peek(1));
|
||||
if (has_error())
|
||||
return ast::StructDecoration::kNone;
|
||||
if (deco == ast::StructDecoration::kNone) {
|
||||
return deco;
|
||||
if (has_error()) {
|
||||
return false;
|
||||
}
|
||||
if (deco == ast::StructDecoration::kNone) {
|
||||
return true;
|
||||
}
|
||||
decos.push_back(deco);
|
||||
|
||||
next(); // Consume the peek of [[
|
||||
next(); // Consume the peek from the struct_decoration
|
||||
|
@ -1489,10 +1499,10 @@ ast::StructDecoration ParserImpl::struct_decoration_decl() {
|
|||
t = next();
|
||||
if (!t.IsAttrRight()) {
|
||||
set_error(t, "missing ]] for struct decoration");
|
||||
return ast::StructDecoration::kNone;
|
||||
return false;
|
||||
}
|
||||
|
||||
return deco;
|
||||
return true;
|
||||
}
|
||||
|
||||
// struct_decoration
|
||||
|
|
|
@ -155,9 +155,11 @@ class ParserImpl {
|
|||
/// Parses a `struct_decl` grammar element
|
||||
/// @returns the struct type or nullptr on error
|
||||
std::unique_ptr<ast::type::StructType> struct_decl();
|
||||
/// Parses a `struct_decoration_decl` grammar element
|
||||
/// @returns the struct decoration or StructDecoraton::kNone
|
||||
ast::StructDecoration struct_decoration_decl();
|
||||
/// Parses a `struct_decoration_decl` grammar element, appending newly
|
||||
/// parsed decorations to the end of |decos|.
|
||||
/// @param decos list to store the parsed decorations
|
||||
/// @returns the true on successful parse; false otherwise
|
||||
bool struct_decoration_decl(ast::StructDecorationList& decos);
|
||||
/// Parses a `struct_decoration` grammar element
|
||||
/// @param t the current token
|
||||
/// @returns the struct decoration or StructDecoraton::kNone if none matched
|
||||
|
@ -177,7 +179,8 @@ class ParserImpl {
|
|||
/// Parses a `function_decl` grammar element
|
||||
/// @returns the parsed function, nullptr otherwise
|
||||
std::unique_ptr<ast::Function> function_decl();
|
||||
/// Parses a `function_decoration_decl` grammar element
|
||||
/// Parses a `function_decoration_decl` grammar element, appending newly
|
||||
/// parsed decorations to the end of |decos|.
|
||||
/// @param decos list to store the parsed decorations
|
||||
/// @returns true on successful parse; false otherwise
|
||||
bool function_decoration_decl(ast::FunctionDecorationList& decos);
|
||||
|
|
|
@ -48,6 +48,26 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithDecoration) {
|
|||
ASSERT_EQ(s->impl()->members().size(), 2u);
|
||||
EXPECT_EQ(s->impl()->members()[0]->name(), "a");
|
||||
EXPECT_EQ(s->impl()->members()[1]->name(), "b");
|
||||
ASSERT_EQ(s->impl()->decorations().size(), 1u);
|
||||
EXPECT_EQ(s->impl()->decorations()[0], ast::StructDecoration::kBlock);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
|
||||
auto* p = parser(R"(
|
||||
[[block]]
|
||||
[[block]] struct {
|
||||
a : f32;
|
||||
b : f32;
|
||||
})");
|
||||
auto s = p->struct_decl();
|
||||
ASSERT_FALSE(p->has_error());
|
||||
ASSERT_NE(s, nullptr);
|
||||
ASSERT_EQ(s->impl()->members().size(), 2u);
|
||||
EXPECT_EQ(s->impl()->members()[0]->name(), "a");
|
||||
EXPECT_EQ(s->impl()->members()[1]->name(), "b");
|
||||
ASSERT_EQ(s->impl()->decorations().size(), 2u);
|
||||
EXPECT_EQ(s->impl()->decorations()[0], ast::StructDecoration::kBlock);
|
||||
EXPECT_EQ(s->impl()->decorations()[1], ast::StructDecoration::kBlock);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecl_EmptyMembers) {
|
||||
|
|
|
@ -23,14 +23,17 @@ namespace {
|
|||
|
||||
TEST_F(ParserImplTest, StructDecorationDecl_Parses) {
|
||||
auto* p = parser("[[block]]");
|
||||
auto d = p->struct_decoration_decl();
|
||||
ast::StructDecorationList decos;
|
||||
ASSERT_TRUE(p->struct_decoration_decl(decos));
|
||||
ASSERT_FALSE(p->has_error());
|
||||
EXPECT_EQ(d, ast::StructDecoration::kBlock);
|
||||
EXPECT_EQ(decos.size(), 1u);
|
||||
EXPECT_EQ(decos[0], ast::StructDecoration::kBlock);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, StructDecorationDecl_MissingAttrRight) {
|
||||
auto* p = parser("[[block");
|
||||
p->struct_decoration_decl();
|
||||
ast::StructDecorationList decos;
|
||||
ASSERT_FALSE(p->struct_decoration_decl(decos));
|
||||
ASSERT_TRUE(p->has_error());
|
||||
EXPECT_EQ(p->error(), "1:8: missing ]] for struct decoration");
|
||||
}
|
||||
|
@ -38,8 +41,10 @@ TEST_F(ParserImplTest, StructDecorationDecl_MissingAttrRight) {
|
|||
// Note, this isn't an error because it could be an array decoration
|
||||
TEST_F(ParserImplTest, StructDecorationDecl_InvalidDecoration) {
|
||||
auto* p = parser("[[invalid]]");
|
||||
p->struct_decoration_decl();
|
||||
ast::StructDecorationList decos;
|
||||
ASSERT_TRUE(p->struct_decoration_decl(decos));
|
||||
ASSERT_FALSE(p->has_error());
|
||||
EXPECT_TRUE(decos.empty());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -226,9 +226,12 @@ void VertexPullingTransform::AddVertexStorageBuffers() {
|
|||
members.push_back(std::make_unique<ast::StructMember>(
|
||||
kStructBufferName, internal_array_type, std::move(member_dec)));
|
||||
|
||||
auto* struct_type = ctx_->type_mgr().Get(
|
||||
std::make_unique<ast::type::StructType>(std::make_unique<ast::Struct>(
|
||||
ast::StructDecoration::kBlock, std::move(members))));
|
||||
ast::StructDecorationList decos;
|
||||
decos.push_back(ast::StructDecoration::kBlock);
|
||||
|
||||
auto* struct_type =
|
||||
ctx_->type_mgr().Get(std::make_unique<ast::type::StructType>(
|
||||
std::make_unique<ast::Struct>(std::move(decos), std::move(members))));
|
||||
|
||||
for (uint32_t i = 0; i < vertex_state_->vertex_buffers.size(); ++i) {
|
||||
// The decorated variable with struct type
|
||||
|
|
|
@ -1022,8 +1022,7 @@ TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
|
|||
members.push_back(std::make_unique<ast::StructMember>("second_member", &f32,
|
||||
std::move(decos)));
|
||||
|
||||
auto strct = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto strct = std::make_unique<ast::Struct>(std::move(members));
|
||||
|
||||
ast::type::StructType st(std::move(strct));
|
||||
|
||||
|
@ -1058,8 +1057,7 @@ TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
|
|||
members.push_back(std::make_unique<ast::StructMember>("second_member", &f32,
|
||||
std::move(decos)));
|
||||
|
||||
auto strct = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto strct = std::make_unique<ast::Struct>(std::move(members));
|
||||
|
||||
auto st = std::make_unique<ast::type::StructType>(std::move(strct));
|
||||
ast::type::AliasType alias("alias", st.get());
|
||||
|
@ -1164,8 +1162,7 @@ TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
|
|||
b_members.push_back(
|
||||
std::make_unique<ast::StructMember>("foo", &vec4, std::move(decos)));
|
||||
|
||||
auto strctB = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(b_members));
|
||||
auto strctB = std::make_unique<ast::Struct>(std::move(b_members));
|
||||
ast::type::StructType stB(std::move(strctB));
|
||||
stB.set_name("B");
|
||||
|
||||
|
@ -1175,8 +1172,7 @@ TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
|
|||
a_members.push_back(
|
||||
std::make_unique<ast::StructMember>("mem", &vecB, std::move(decos)));
|
||||
|
||||
auto strctA = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(a_members));
|
||||
auto strctA = std::make_unique<ast::Struct>(std::move(a_members));
|
||||
|
||||
ast::type::StructType stA(std::move(strctA));
|
||||
stA.set_name("A");
|
||||
|
|
|
@ -261,9 +261,11 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_WithDecoration) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
|
||||
|
||||
auto str = std::make_unique<ast::Struct>();
|
||||
str->set_members(std::move(members));
|
||||
str->set_decoration(ast::StructDecoration::kBlock);
|
||||
ast::StructDecorationList decos;
|
||||
decos.push_back(ast::StructDecoration::kBlock);
|
||||
|
||||
auto str =
|
||||
std::make_unique<ast::Struct>(std::move(decos), std::move(members));
|
||||
|
||||
ast::type::StructType s(std::move(str));
|
||||
|
||||
|
|
|
@ -296,9 +296,10 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
|
||||
|
||||
auto str = std::make_unique<ast::Struct>();
|
||||
str->set_members(std::move(members));
|
||||
str->set_decoration(ast::StructDecoration::kBlock);
|
||||
ast::StructDecorationList decos;
|
||||
decos.push_back(ast::StructDecoration::kBlock);
|
||||
auto str =
|
||||
std::make_unique<ast::Struct>(std::move(decos), std::move(members));
|
||||
|
||||
ast::type::StructType s(std::move(str));
|
||||
|
||||
|
|
|
@ -2384,14 +2384,9 @@ bool Builder::GenerateStructType(ast::type::StructType* struct_type,
|
|||
OperandList ops;
|
||||
ops.push_back(result);
|
||||
|
||||
if (impl->decoration() == ast::StructDecoration::kBlock) {
|
||||
if (impl->IsBlockDecorated()) {
|
||||
push_annot(spv::Op::OpDecorate,
|
||||
{Operand::Int(struct_id), Operand::Int(SpvDecorationBlock)});
|
||||
} else {
|
||||
if (impl->decoration() != ast::StructDecoration::kNone) {
|
||||
error_ = "unknown struct decoration";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto& members = impl->members();
|
||||
|
|
|
@ -305,8 +305,7 @@ TEST_F(BuilderTest, MemberAccessor) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
|
@ -363,15 +362,15 @@ TEST_F(BuilderTest, MemberAccessor_Nested) {
|
|||
inner_members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
|
||||
|
||||
ast::type::StructType inner_struct(std::make_unique<ast::Struct>(
|
||||
ast::StructDecoration::kNone, std::move(inner_members)));
|
||||
ast::type::StructType inner_struct(
|
||||
std::make_unique<ast::Struct>(std::move(inner_members)));
|
||||
|
||||
ast::StructMemberList outer_members;
|
||||
outer_members.push_back(std::make_unique<ast::StructMember>(
|
||||
"inner", &inner_struct, std::move(decos)));
|
||||
|
||||
ast::type::StructType s_type(std::make_unique<ast::Struct>(
|
||||
ast::StructDecoration::kNone, std::move(outer_members)));
|
||||
ast::type::StructType s_type(
|
||||
std::make_unique<ast::Struct>(std::move(outer_members)));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
|
||||
|
@ -431,8 +430,8 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
|
|||
inner_members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
|
||||
|
||||
ast::type::StructType inner_struct(std::make_unique<ast::Struct>(
|
||||
ast::StructDecoration::kNone, std::move(inner_members)));
|
||||
ast::type::StructType inner_struct(
|
||||
std::make_unique<ast::Struct>(std::move(inner_members)));
|
||||
|
||||
ast::type::AliasType alias("Inner", &inner_struct);
|
||||
|
||||
|
@ -440,8 +439,8 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
|
|||
outer_members.push_back(
|
||||
std::make_unique<ast::StructMember>("inner", &alias, std::move(decos)));
|
||||
|
||||
ast::type::StructType s_type(std::make_unique<ast::Struct>(
|
||||
ast::StructDecoration::kNone, std::move(outer_members)));
|
||||
ast::type::StructType s_type(
|
||||
std::make_unique<ast::Struct>(std::move(outer_members)));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
|
||||
|
@ -501,15 +500,15 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) {
|
|||
inner_members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
|
||||
|
||||
ast::type::StructType inner_struct(std::make_unique<ast::Struct>(
|
||||
ast::StructDecoration::kNone, std::move(inner_members)));
|
||||
ast::type::StructType inner_struct(
|
||||
std::make_unique<ast::Struct>(std::move(inner_members)));
|
||||
|
||||
ast::StructMemberList outer_members;
|
||||
outer_members.push_back(std::make_unique<ast::StructMember>(
|
||||
"inner", &inner_struct, std::move(decos)));
|
||||
|
||||
ast::type::StructType s_type(std::make_unique<ast::Struct>(
|
||||
ast::StructDecoration::kNone, std::move(outer_members)));
|
||||
ast::type::StructType s_type(
|
||||
std::make_unique<ast::Struct>(std::move(outer_members)));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
|
||||
|
@ -576,15 +575,15 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) {
|
|||
inner_members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
|
||||
|
||||
ast::type::StructType inner_struct(std::make_unique<ast::Struct>(
|
||||
ast::StructDecoration::kNone, std::move(inner_members)));
|
||||
ast::type::StructType inner_struct(
|
||||
std::make_unique<ast::Struct>(std::move(inner_members)));
|
||||
|
||||
ast::StructMemberList outer_members;
|
||||
outer_members.push_back(std::make_unique<ast::StructMember>(
|
||||
"inner", &inner_struct, std::move(decos)));
|
||||
|
||||
ast::type::StructType s_type(std::make_unique<ast::Struct>(
|
||||
ast::StructDecoration::kNone, std::move(outer_members)));
|
||||
ast::type::StructType s_type(
|
||||
std::make_unique<ast::Struct>(std::move(outer_members)));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
ast::Variable var("ident", ast::StorageClass::kFunction, &s_type);
|
||||
|
@ -863,15 +862,13 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
|
|||
ast::StructMemberList members;
|
||||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("baz", &vec3, std::move(decos)));
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType c_type(std::move(s));
|
||||
c_type.set_name("C");
|
||||
|
||||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("bar", &c_type, std::move(decos)));
|
||||
s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType b_type(std::move(s));
|
||||
b_type.set_name("B");
|
||||
|
||||
|
@ -879,8 +876,7 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
|
|||
|
||||
members.push_back(std::make_unique<ast::StructMember>("foo", &b_ary_type,
|
||||
std::move(decos)));
|
||||
s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType a_type(std::move(s));
|
||||
a_type.set_name("A");
|
||||
|
||||
|
|
|
@ -269,8 +269,7 @@ TEST_F(BuilderTest, Assign_StructMember) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
|
|
|
@ -1747,8 +1747,7 @@ TEST_F(BuilderTest, Constructor_Type_Struct) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &vec, std::move(decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
|
@ -1959,8 +1958,7 @@ TEST_F(BuilderTest, Constructor_Type_ZeroInit_Struct) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
|
|
|
@ -2732,8 +2732,7 @@ TEST_F(BuilderTest, Call_ArrayLength) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("a", &ary, std::move(decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
|
@ -2792,8 +2791,7 @@ TEST_F(BuilderTest, Call_ArrayLength_OtherMembersInStruct) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("a", &ary, std::move(decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
|
@ -2854,8 +2852,7 @@ TEST_F(BuilderTest, DISABLED_Call_ArrayLength_Ptr) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("a", &ary, std::move(decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
|
|
|
@ -328,8 +328,7 @@ TEST_F(BuilderTest_Type, GenerateStruct) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
s_type.set_name("my_struct");
|
||||
|
||||
|
@ -355,7 +354,10 @@ TEST_F(BuilderTest_Type, GenerateStruct_Decorated) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kBlock,
|
||||
ast::StructDecorationList struct_decos;
|
||||
struct_decos.push_back(ast::StructDecoration::kBlock);
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(std::move(struct_decos),
|
||||
std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
s_type.set_name("my_struct");
|
||||
|
@ -390,8 +392,7 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(b_decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
|
||||
ast::Module mod;
|
||||
|
@ -429,8 +430,7 @@ TEST_F(BuilderTest_Type, GenerateStruct_NonLayout_Matrix) {
|
|||
members.push_back(std::make_unique<ast::StructMember>("c", &glsl_mat4x4,
|
||||
std::move(empty_c)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
|
||||
ast::Module mod;
|
||||
|
@ -477,8 +477,7 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutMatrix) {
|
|||
members.push_back(std::make_unique<ast::StructMember>("c", &glsl_mat4x4,
|
||||
std::move(c_decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
|
||||
ast::Module mod;
|
||||
|
@ -543,8 +542,7 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutArraysOfMatrix) {
|
|||
members.push_back(std::make_unique<ast::StructMember>("c", &glsl_mat4x4,
|
||||
std::move(c_decos)));
|
||||
|
||||
auto s = std::make_unique<ast::Struct>(ast::StructDecoration::kNone,
|
||||
std::move(members));
|
||||
auto s = std::make_unique<ast::Struct>(std::move(members));
|
||||
ast::type::StructType s_type(std::move(s));
|
||||
|
||||
ast::Module mod;
|
||||
|
|
|
@ -437,8 +437,8 @@ bool GeneratorImpl::EmitType(ast::type::Type* type) {
|
|||
}
|
||||
} else if (type->IsStruct()) {
|
||||
auto* str = type->AsStruct()->impl();
|
||||
if (str->decoration() != ast::StructDecoration::kNone) {
|
||||
out_ << "[[" << str->decoration() << "]] ";
|
||||
for (auto deco : str->decorations()) {
|
||||
out_ << "[[" << deco << "]]" << std::endl;
|
||||
}
|
||||
out_ << "struct {" << std::endl;
|
||||
|
||||
|
|
|
@ -160,15 +160,18 @@ TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithDecoration) {
|
|||
members.push_back(
|
||||
std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
|
||||
|
||||
auto str = std::make_unique<ast::Struct>();
|
||||
str->set_members(std::move(members));
|
||||
str->set_decoration(ast::StructDecoration::kBlock);
|
||||
ast::StructDecorationList decos;
|
||||
decos.push_back(ast::StructDecoration::kBlock);
|
||||
|
||||
auto str =
|
||||
std::make_unique<ast::Struct>(std::move(decos), std::move(members));
|
||||
|
||||
ast::type::StructType s(std::move(str));
|
||||
|
||||
GeneratorImpl g;
|
||||
ASSERT_TRUE(g.EmitType(&s)) << g.error();
|
||||
EXPECT_EQ(g.result(), R"([[block]] struct {
|
||||
EXPECT_EQ(g.result(), R"([[block]]
|
||||
struct {
|
||||
a : i32;
|
||||
[[offset(4)]] b : f32;
|
||||
})");
|
||||
|
|
Loading…
Reference in New Issue