Store struct member location into the sem.
This CL adds the `@location` of a Struct Member into the `StructMember` sem object as a `std::optional<uint32_t>`. The resolver then populates the location value if an attribute is found during resolution. This will provide a place to store the evaluated expression value for a location in the future. Bug: tint:1633 Change-Id: I6f696968dddf95af1f933d96cdb4a7630badac2e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/101062 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
8dc97a8e3d
commit
97c9e0ba9f
|
@ -149,11 +149,11 @@ TEST_F(ResolverInferredTypeTest, InferStruct_Pass) {
|
|||
auto* member = Member("x", ty.i32());
|
||||
auto* str = Structure("S", utils::Vector{member});
|
||||
|
||||
auto* expected_type =
|
||||
create<sem::Struct>(str, str->name,
|
||||
sem::StructMemberList{create<sem::StructMember>(
|
||||
member, member->symbol, create<sem::I32>(), 0u, 0u, 0u, 4u)},
|
||||
0u, 4u, 4u);
|
||||
auto* expected_type = create<sem::Struct>(
|
||||
str, str->name,
|
||||
sem::StructMemberList{create<sem::StructMember>(member, member->symbol, create<sem::I32>(),
|
||||
0u, 0u, 0u, 4u, std::nullopt)},
|
||||
0u, 4u, 4u);
|
||||
|
||||
auto* ctor_expr = Construct(ty.Of(str));
|
||||
|
||||
|
|
|
@ -793,7 +793,8 @@ const sem::Struct* build_struct(MatchState& state,
|
|||
/* index */ static_cast<uint32_t>(members.size()),
|
||||
/* offset */ offset,
|
||||
/* align */ align,
|
||||
/* size */ size));
|
||||
/* size */ size,
|
||||
/* location */ std::nullopt));
|
||||
offset += size;
|
||||
}
|
||||
uint32_t size_without_padding = offset;
|
||||
|
|
|
@ -2747,6 +2747,7 @@ sem::Struct* Resolver::Structure(const ast::Struct* str) {
|
|||
bool has_offset_attr = false;
|
||||
bool has_align_attr = false;
|
||||
bool has_size_attr = false;
|
||||
std::optional<uint32_t> location;
|
||||
for (auto* attr : member->attributes) {
|
||||
Mark(attr);
|
||||
if (auto* o = attr->As<ast::StructMemberOffsetAttribute>()) {
|
||||
|
@ -2760,11 +2761,7 @@ sem::Struct* Resolver::Structure(const ast::Struct* str) {
|
|||
align = 1;
|
||||
has_offset_attr = true;
|
||||
} else if (auto* a = attr->As<ast::StructMemberAlignAttribute>()) {
|
||||
const auto* expr = Expression(a->align);
|
||||
if (!expr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto* materialized = Materialize(expr);
|
||||
auto* materialized = Materialize(Expression(a->align));
|
||||
if (!materialized) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -2790,6 +2787,8 @@ sem::Struct* Resolver::Structure(const ast::Struct* str) {
|
|||
}
|
||||
size = s->size;
|
||||
has_size_attr = true;
|
||||
} else if (auto* l = attr->As<ast::LocationAttribute>()) {
|
||||
location = l->value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2811,7 +2810,7 @@ sem::Struct* Resolver::Structure(const ast::Struct* str) {
|
|||
auto* sem_member = builder_->create<sem::StructMember>(
|
||||
member, member->symbol, type, static_cast<uint32_t>(sem_members.size()),
|
||||
static_cast<uint32_t>(offset), static_cast<uint32_t>(align),
|
||||
static_cast<uint32_t>(size));
|
||||
static_cast<uint32_t>(size), location);
|
||||
builder_->Sem().Add(member, sem_member);
|
||||
sem_members.emplace_back(sem_member);
|
||||
|
||||
|
|
|
@ -174,6 +174,20 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamViaAlias) {
|
|||
UnorderedElementsAre(sem::PipelineStageUsage::kFragmentInput));
|
||||
}
|
||||
|
||||
TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamLocationSet) {
|
||||
auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(3)})});
|
||||
|
||||
Func("main", utils::Vector{Param("param", ty.Of(s))}, ty.void_(), utils::Empty,
|
||||
utils::Vector{Stage(ast::PipelineStage::kFragment)});
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
auto* sem = TypeOf(s)->As<sem::Struct>();
|
||||
ASSERT_NE(sem, nullptr);
|
||||
ASSERT_EQ(1u, sem->Members().size());
|
||||
EXPECT_EQ(3u, sem->Members()[0]->Location());
|
||||
}
|
||||
|
||||
TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeViaAlias) {
|
||||
auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(0)})});
|
||||
auto* s_alias = Alias("S_alias", ty.Of(s));
|
||||
|
@ -190,5 +204,19 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeViaAlias) {
|
|||
UnorderedElementsAre(sem::PipelineStageUsage::kFragmentOutput));
|
||||
}
|
||||
|
||||
TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeLocationSet) {
|
||||
auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{Location(3)})});
|
||||
|
||||
Func("main", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s), Expr(0_f)))},
|
||||
utils::Vector{Stage(ast::PipelineStage::kFragment)});
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
auto* sem = TypeOf(s)->As<sem::Struct>();
|
||||
ASSERT_NE(sem, nullptr);
|
||||
ASSERT_EQ(1u, sem->Members().size());
|
||||
EXPECT_EQ(3u, sem->Members()[0]->Location());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::resolver
|
||||
|
|
|
@ -105,5 +105,23 @@ TEST_F(StructTest, Layout) {
|
|||
/* */ };)");
|
||||
}
|
||||
|
||||
TEST_F(StructTest, Location) {
|
||||
auto* st = Structure("st", utils::Vector{
|
||||
Member("a", ty.i32(), utils::Vector{Location(1u)}),
|
||||
Member("b", ty.u32()),
|
||||
});
|
||||
|
||||
auto p = Build();
|
||||
ASSERT_TRUE(p.IsValid()) << p.Diagnostics().str();
|
||||
|
||||
auto* sem = p.Sem().Get(st);
|
||||
ASSERT_EQ(2u, sem->Members().size());
|
||||
|
||||
EXPECT_TRUE(sem->Members()[0]->Location().has_value());
|
||||
EXPECT_EQ(sem->Members()[0]->Location().value(), 1u);
|
||||
|
||||
EXPECT_FALSE(sem->Members()[1]->Location().has_value());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::sem
|
||||
|
|
|
@ -161,14 +161,16 @@ StructMember::StructMember(const ast::StructMember* declaration,
|
|||
uint32_t index,
|
||||
uint32_t offset,
|
||||
uint32_t align,
|
||||
uint32_t size)
|
||||
uint32_t size,
|
||||
std::optional<uint32_t> location)
|
||||
: declaration_(declaration),
|
||||
name_(name),
|
||||
type_(type),
|
||||
index_(index),
|
||||
offset_(offset),
|
||||
align_(align),
|
||||
size_(size) {}
|
||||
size_(size),
|
||||
location_(location) {}
|
||||
|
||||
StructMember::~StructMember() = default;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
@ -180,13 +181,15 @@ class StructMember final : public Castable<StructMember, Node> {
|
|||
/// @param offset the byte offset from the base of the structure
|
||||
/// @param align the byte alignment of the member
|
||||
/// @param size the byte size of the member
|
||||
/// @param location the location attribute, if present
|
||||
StructMember(const ast::StructMember* declaration,
|
||||
Symbol name,
|
||||
const sem::Type* type,
|
||||
uint32_t index,
|
||||
uint32_t offset,
|
||||
uint32_t align,
|
||||
uint32_t size);
|
||||
uint32_t size,
|
||||
std::optional<uint32_t> location);
|
||||
|
||||
/// Destructor
|
||||
~StructMember() override;
|
||||
|
@ -219,6 +222,9 @@ class StructMember final : public Castable<StructMember, Node> {
|
|||
/// @returns byte size
|
||||
uint32_t Size() const { return size_; }
|
||||
|
||||
/// @returns the location, if set
|
||||
std::optional<uint32_t> Location() const { return location_; }
|
||||
|
||||
private:
|
||||
const ast::StructMember* const declaration_;
|
||||
const Symbol name_;
|
||||
|
@ -228,6 +234,7 @@ class StructMember final : public Castable<StructMember, Node> {
|
|||
const uint32_t offset_;
|
||||
const uint32_t align_;
|
||||
const uint32_t size_;
|
||||
const std::optional<uint32_t> location_;
|
||||
};
|
||||
|
||||
} // namespace tint::sem
|
||||
|
|
|
@ -54,7 +54,8 @@ struct TypeTest : public TestHelper {
|
|||
/* index */ 0u,
|
||||
/* offset */ 0u,
|
||||
/* align */ 4u,
|
||||
/* size */ 4u),
|
||||
/* size */ 4u,
|
||||
/* location */ std::nullopt),
|
||||
},
|
||||
/* align*/ 4u,
|
||||
/* size*/ 4u,
|
||||
|
|
Loading…
Reference in New Issue