Implement Default Struct Layout

Implements https://github.com/gpuweb/gpuweb/pull/1447

SPIR-V Reader is still TODO, but continues to function as the offset
decoration is still supported.

Bug: tint:626
Bug: tint:629
Change-Id: Id574eb3a5c6729559382812de37b23f0c68fd406
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/43640
Commit-Queue: Ben Clayton <bclayton@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
Ben Clayton
2021-03-15 10:43:11 +00:00
committed by Commit Bot service account
parent 717fbbf183
commit d614dd5d12
107 changed files with 2401 additions and 2038 deletions

View File

@@ -28,9 +28,8 @@ TEST(ModuleCloneTest, Clone) {
// See also fuzzers/tint_ast_clone_fuzzer.cc for further coverage of cloning.
Source::File file("test.wgsl", R"([[block]]
struct S {
[[offset(0)]]
[[size(4)]]
m0 : u32;
[[offset(4)]]
m1 : array<u32>;
};
@@ -38,7 +37,7 @@ const c0 : i32 = 10;
const c1 : bool = true;
type t0 = [[stride(16)]] array<vec4<f32>>;
type t1 = [[stride(32)]] array<vec4<f32>>;
type t1 = array<vec4<f32>>;
var<uniform> g0 : u32 = 20u;
var<out> g1 : f32 = 123.0;

View File

@@ -0,0 +1,46 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/struct_member_align_decoration.h"
#include "src/clone_context.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberAlignDecoration);
namespace tint {
namespace ast {
StructMemberAlignDecoration::StructMemberAlignDecoration(const Source& source,
uint32_t align)
: Base(source), align_(align) {}
StructMemberAlignDecoration::~StructMemberAlignDecoration() = default;
void StructMemberAlignDecoration::to_str(const semantic::Info&,
std::ostream& out,
size_t indent) const {
make_indent(out, indent);
out << "align " << std::to_string(align_);
}
StructMemberAlignDecoration* StructMemberAlignDecoration::Clone(
CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<StructMemberAlignDecoration>(src, align_);
}
} // namespace ast
} // namespace tint

View File

@@ -0,0 +1,59 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
#define SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_
#include <stddef.h>
#include "src/ast/decoration.h"
namespace tint {
namespace ast {
/// A struct member align decoration
class StructMemberAlignDecoration
: public Castable<StructMemberAlignDecoration, Decoration> {
public:
/// constructor
/// @param source the source of this decoration
/// @param align the align value
StructMemberAlignDecoration(const Source& source, uint32_t align);
~StructMemberAlignDecoration() override;
/// @returns the align value
uint32_t align() const { return align_; }
/// Outputs the decoration to the given stream
/// @param sem the semantic info for the program
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(const semantic::Info& sem,
std::ostream& out,
size_t indent) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
StructMemberAlignDecoration* Clone(CloneContext* ctx) const override;
private:
uint32_t const align_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_STRUCT_MEMBER_ALIGN_DECORATION_H_

View File

@@ -0,0 +1,37 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/struct_member_align_decoration.h"
#include "src/ast/test_helper.h"
namespace tint {
namespace ast {
namespace {
using StructMemberAlignDecorationTest = TestHelper;
TEST_F(StructMemberAlignDecorationTest, Creation) {
auto* d = create<StructMemberAlignDecoration>(2);
EXPECT_EQ(2u, d->align());
}
TEST_F(StructMemberAlignDecorationTest, Is) {
auto* d = create<StructMemberAlignDecoration>(2);
EXPECT_TRUE(d->Is<StructMemberAlignDecoration>());
}
} // namespace
} // namespace ast
} // namespace tint

View File

@@ -21,6 +21,8 @@ namespace tint {
namespace ast {
/// A struct member offset decoration
// [DEPRECATED] - Replaced with StructMemberAlignDecoration and
// StructMemberSizeDecoration
class StructMemberOffsetDecoration
: public Castable<StructMemberOffsetDecoration, Decoration> {
public:

View File

@@ -0,0 +1,46 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/struct_member_size_decoration.h"
#include "src/clone_context.h"
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StructMemberSizeDecoration);
namespace tint {
namespace ast {
StructMemberSizeDecoration::StructMemberSizeDecoration(const Source& source,
uint32_t size)
: Base(source), size_(size) {}
StructMemberSizeDecoration::~StructMemberSizeDecoration() = default;
void StructMemberSizeDecoration::to_str(const semantic::Info&,
std::ostream& out,
size_t indent) const {
make_indent(out, indent);
out << "size " << std::to_string(size_);
}
StructMemberSizeDecoration* StructMemberSizeDecoration::Clone(
CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<StructMemberSizeDecoration>(src, size_);
}
} // namespace ast
} // namespace tint

View File

@@ -0,0 +1,59 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
#define SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_
#include <stddef.h>
#include "src/ast/decoration.h"
namespace tint {
namespace ast {
/// A struct member size decoration
class StructMemberSizeDecoration
: public Castable<StructMemberSizeDecoration, Decoration> {
public:
/// constructor
/// @param source the source of this decoration
/// @param size the size value
StructMemberSizeDecoration(const Source& source, uint32_t size);
~StructMemberSizeDecoration() override;
/// @returns the size value
uint32_t size() const { return size_; }
/// Outputs the decoration to the given stream
/// @param sem the semantic info for the program
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(const semantic::Info& sem,
std::ostream& out,
size_t indent) const override;
/// Clones this node and all transitive child nodes using the `CloneContext`
/// `ctx`.
/// @param ctx the clone context
/// @return the newly cloned node
StructMemberSizeDecoration* Clone(CloneContext* ctx) const override;
private:
uint32_t const size_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_STRUCT_MEMBER_SIZE_DECORATION_H_

View File

@@ -0,0 +1,37 @@
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/struct_member_size_decoration.h"
#include "src/ast/test_helper.h"
namespace tint {
namespace ast {
namespace {
using StructMemberOffsetDecorationTest = TestHelper;
TEST_F(StructMemberOffsetDecorationTest, Creation) {
auto* d = create<StructMemberSizeDecoration>(2);
EXPECT_EQ(2u, d->size());
}
TEST_F(StructMemberOffsetDecorationTest, Is) {
auto* d = create<StructMemberSizeDecoration>(2);
EXPECT_TRUE(d->Is<StructMemberSizeDecoration>());
}
} // namespace
} // namespace ast
} // namespace tint

View File

@@ -22,11 +22,11 @@ namespace {
using StructMemberTest = TestHelper;
TEST_F(StructMemberTest, Creation) {
auto* st = Member("a", ty.i32(), {MemberOffset(4)});
auto* st = Member("a", ty.i32(), {MemberSize(4)});
EXPECT_EQ(st->symbol(), Symbol(1));
EXPECT_EQ(st->type(), ty.i32());
EXPECT_EQ(st->decorations().size(), 1u);
EXPECT_TRUE(st->decorations()[0]->Is<StructMemberOffsetDecoration>());
EXPECT_TRUE(st->decorations()[0]->Is<StructMemberSizeDecoration>());
EXPECT_EQ(st->source().range.begin.line, 0u);
EXPECT_EQ(st->source().range.begin.column, 0u);
EXPECT_EQ(st->source().range.end.line, 0u);
@@ -68,14 +68,14 @@ TEST_F(StructMemberTest, Assert_NullDecoration) {
EXPECT_FATAL_FAILURE(
{
ProgramBuilder b;
b.Member("a", b.ty.i32(), {b.MemberOffset(4), nullptr});
b.Member("a", b.ty.i32(), {b.MemberSize(4), nullptr});
},
"internal compiler error");
}
TEST_F(StructMemberTest, ToStr) {
auto* st = Member("a", ty.i32(), {MemberOffset(4)});
EXPECT_EQ(str(st), "StructMember{[[ offset 4 ]] a: __i32}\n");
auto* st = Member("a", ty.i32(), {MemberSize(4)});
EXPECT_EQ(str(st), "StructMember{[[ size 4 ]] a: __i32}\n");
}
TEST_F(StructMemberTest, ToStrNoDecorations) {