ProgramBuilder: Migrate any remaining types to typ::*

Used as a stepping stone to emitting the ast::Types instead.

Bug: tint:724
Change-Id: Ib2d6c150fe8aa7c1e2c502676922b14b1518a4be
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/48686
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton 2021-04-22 14:40:23 +00:00 committed by Commit Bot service account
parent 7241a504f0
commit e204f27f86
58 changed files with 1256 additions and 1255 deletions

View File

@ -132,7 +132,7 @@ std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data) {
return out; return out;
} }
sem::Type* TextureOverloadCase::resultVectorComponentType( typ::Type TextureOverloadCase::resultVectorComponentType(
ProgramBuilder* b) const { ProgramBuilder* b) const {
switch (texture_data_type) { switch (texture_data_type) {
case ast::intrinsic::test::TextureDataType::kF32: case ast::intrinsic::test::TextureDataType::kF32:
@ -144,12 +144,12 @@ sem::Type* TextureOverloadCase::resultVectorComponentType(
} }
TINT_UNREACHABLE(b->Diagnostics()); TINT_UNREACHABLE(b->Diagnostics());
return nullptr; return {};
} }
ast::Variable* TextureOverloadCase::buildTextureVariable( ast::Variable* TextureOverloadCase::buildTextureVariable(
ProgramBuilder* b) const { ProgramBuilder* b) const {
auto* datatype = resultVectorComponentType(b); auto datatype = resultVectorComponentType(b);
DecorationList decos = { DecorationList decos = {
b->create<ast::GroupDecoration>(0), b->create<ast::GroupDecoration>(0),
@ -157,27 +157,23 @@ ast::Variable* TextureOverloadCase::buildTextureVariable(
}; };
switch (texture_kind) { switch (texture_kind) {
case ast::intrinsic::test::TextureKind::kRegular: case ast::intrinsic::test::TextureKind::kRegular:
return b->Global( return b->Global("texture",
"texture", b->ty.sampled_texture(texture_dimension, datatype),
b->create<sem::SampledTexture>(texture_dimension, datatype),
ast::StorageClass::kUniformConstant, nullptr, decos); ast::StorageClass::kUniformConstant, nullptr, decos);
case ast::intrinsic::test::TextureKind::kDepth: case ast::intrinsic::test::TextureKind::kDepth:
return b->Global("texture", return b->Global("texture", b->ty.depth_texture(texture_dimension),
b->create<sem::DepthTexture>(texture_dimension),
ast::StorageClass::kUniformConstant, nullptr, decos); ast::StorageClass::kUniformConstant, nullptr, decos);
case ast::intrinsic::test::TextureKind::kMultisampled: case ast::intrinsic::test::TextureKind::kMultisampled:
return b->Global( return b->Global(
"texture", "texture",
b->create<sem::MultisampledTexture>(texture_dimension, datatype), b->ty.multisampled_texture(texture_dimension, datatype),
ast::StorageClass::kUniformConstant, nullptr, decos); ast::StorageClass::kUniformConstant, nullptr, decos);
case ast::intrinsic::test::TextureKind::kStorage: { case ast::intrinsic::test::TextureKind::kStorage: {
auto* st = b->create<sem::StorageTexture>(texture_dimension, image_format, auto st = b->ty.storage_texture(texture_dimension, image_format);
datatype); auto ac = b->ty.access(access_control, st);
auto* ac = b->create<sem::AccessControl>(access_control, st);
return b->Global("texture", ac, ast::StorageClass::kUniformConstant, return b->Global("texture", ac, ast::StorageClass::kUniformConstant,
nullptr, decos); nullptr, decos);
} }
@ -193,7 +189,7 @@ ast::Variable* TextureOverloadCase::buildSamplerVariable(
b->create<ast::GroupDecoration>(0), b->create<ast::GroupDecoration>(0),
b->create<ast::BindingDecoration>(1), b->create<ast::BindingDecoration>(1),
}; };
return b->Global("sampler", b->create<sem::Sampler>(sampler_kind), return b->Global("sampler", b->ty.sampler(sampler_kind),
ast::StorageClass::kUniformConstant, nullptr, decos); ast::StorageClass::kUniformConstant, nullptr, decos);
} }

View File

@ -209,7 +209,7 @@ struct TextureOverloadCase {
/// @param builder the AST builder used for the test /// @param builder the AST builder used for the test
/// @returns the vector component type of the texture function return value /// @returns the vector component type of the texture function return value
sem::Type* resultVectorComponentType(ProgramBuilder* builder) const; typ::Type resultVectorComponentType(ProgramBuilder* builder) const;
/// @param builder the AST builder used for the test /// @param builder the AST builder used for the test
/// @returns a variable holding the test texture, automatically registered as /// @returns a variable holding the test texture, automatically registered as
/// a global variable. /// a global variable.

View File

@ -29,9 +29,7 @@ namespace {
class InspectorHelper : public ProgramBuilder { class InspectorHelper : public ProgramBuilder {
public: public:
InspectorHelper() InspectorHelper() {}
: sampler_type_(ast::SamplerKind::kSampler),
comparison_sampler_type_(ast::SamplerKind::kComparisonSampler) {}
/// Generates an empty function /// Generates an empty function
/// @param name name of the function created /// @param name name of the function created
@ -62,7 +60,7 @@ class InspectorHelper : public ProgramBuilder {
/// Generates a struct that contains user-defined IO members /// Generates a struct that contains user-defined IO members
/// @param name the name of the generated struct /// @param name the name of the generated struct
/// @param inout_vars tuples of {name, loc} that will be the struct members /// @param inout_vars tuples of {name, loc} that will be the struct members
sem::StructType* MakeInOutStruct( typ::Struct MakeInOutStruct(
std::string name, std::string name,
std::vector<std::tuple<std::string, uint32_t>> inout_vars) { std::vector<std::tuple<std::string, uint32_t>> inout_vars) {
ast::StructMemberList members; ast::StructMemberList members;
@ -146,7 +144,7 @@ class InspectorHelper : public ProgramBuilder {
/// @param val value to initialize the variable with, if NULL no initializer /// @param val value to initialize the variable with, if NULL no initializer
/// will be added. /// will be added.
template <class T> template <class T>
void AddConstantID(std::string name, uint32_t id, sem::Type* type, T* val) { void AddConstantID(std::string name, uint32_t id, typ::Type type, T* val) {
ast::Expression* constructor = nullptr; ast::Expression* constructor = nullptr;
if (val) { if (val) {
constructor = constructor =
@ -161,28 +159,28 @@ class InspectorHelper : public ProgramBuilder {
/// @param type AST type of the literal, must resolve to BoolLiteral /// @param type AST type of the literal, must resolve to BoolLiteral
/// @param val scalar value for the literal to contain /// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value /// @returns a Literal of the expected type and value
ast::Literal* MakeLiteral(sem::Type* type, bool* val) { ast::Literal* MakeLiteral(typ::Type type, bool* val) {
return create<ast::BoolLiteral>(type, *val); return create<ast::BoolLiteral>(type, *val);
} }
/// @param type AST type of the literal, must resolve to UIntLiteral /// @param type AST type of the literal, must resolve to UIntLiteral
/// @param val scalar value for the literal to contain /// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value /// @returns a Literal of the expected type and value
ast::Literal* MakeLiteral(sem::Type* type, uint32_t* val) { ast::Literal* MakeLiteral(typ::Type type, uint32_t* val) {
return create<ast::UintLiteral>(type, *val); return create<ast::UintLiteral>(type, *val);
} }
/// @param type AST type of the literal, must resolve to IntLiteral /// @param type AST type of the literal, must resolve to IntLiteral
/// @param val scalar value for the literal to contain /// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value /// @returns a Literal of the expected type and value
ast::Literal* MakeLiteral(sem::Type* type, int32_t* val) { ast::Literal* MakeLiteral(typ::Type type, int32_t* val) {
return create<ast::SintLiteral>(type, *val); return create<ast::SintLiteral>(type, *val);
} }
/// @param type AST type of the literal, must resolve to FloattLiteral /// @param type AST type of the literal, must resolve to FloattLiteral
/// @param val scalar value for the literal to contain /// @param val scalar value for the literal to contain
/// @returns a Literal of the expected type and value /// @returns a Literal of the expected type and value
ast::Literal* MakeLiteral(sem::Type* type, float* val) { ast::Literal* MakeLiteral(typ::Type type, float* val) {
return create<ast::FloatLiteral>(type, *val); return create<ast::FloatLiteral>(type, *val);
} }
@ -203,7 +201,7 @@ class InspectorHelper : public ProgramBuilder {
/// @param idx index of member /// @param idx index of member
/// @param type type of member /// @param type type of member
/// @returns a string for the member /// @returns a string for the member
std::string StructMemberName(size_t idx, sem::Type* type) { std::string StructMemberName(size_t idx, typ::Type type) {
return std::to_string(idx) + type->type_name(); return std::to_string(idx) + type->type_name();
} }
@ -212,11 +210,11 @@ class InspectorHelper : public ProgramBuilder {
/// @param member_types a vector of member types /// @param member_types a vector of member types
/// @param is_block whether or not to decorate as a Block /// @param is_block whether or not to decorate as a Block
/// @returns a struct type /// @returns a struct type
sem::StructType* MakeStructType(const std::string& name, typ::Struct MakeStructType(const std::string& name,
std::vector<sem::Type*> member_types, std::vector<typ::Type> member_types,
bool is_block) { bool is_block) {
ast::StructMemberList members; ast::StructMemberList members;
for (auto* type : member_types) { for (auto type : member_types) {
members.push_back(Member(StructMemberName(members.size(), type), type)); members.push_back(Member(StructMemberName(members.size(), type), type));
} }
@ -232,10 +230,9 @@ class InspectorHelper : public ProgramBuilder {
/// @param name name for the type /// @param name name for the type
/// @param member_types a vector of member types /// @param member_types a vector of member types
/// @returns a struct type that has the layout for an uniform buffer. /// @returns a struct type that has the layout for an uniform buffer.
sem::StructType* MakeUniformBufferType(const std::string& name, typ::Struct MakeUniformBufferType(const std::string& name,
std::vector<sem::Type*> member_types) { std::vector<typ::Type> member_types) {
auto* struct_type = MakeStructType(name, member_types, true); return MakeStructType(name, member_types, true);
return struct_type;
} }
/// Generates types appropriate for using in a storage buffer /// Generates types appropriate for using in a storage buffer
@ -244,12 +241,11 @@ class InspectorHelper : public ProgramBuilder {
/// @returns a tuple {struct type, access control type}, where the struct has /// @returns a tuple {struct type, access control type}, where the struct has
/// the layout for a storage buffer, and the control type wraps the /// the layout for a storage buffer, and the control type wraps the
/// struct. /// struct.
std::tuple<sem::StructType*, sem::AccessControl*> MakeStorageBufferTypes( std::tuple<typ::Struct, typ::AccessControl> MakeStorageBufferTypes(
const std::string& name, const std::string& name,
std::vector<sem::Type*> member_types) { std::vector<typ::Type> member_types) {
auto* struct_type = MakeStructType(name, member_types, true); auto struct_type = MakeStructType(name, member_types, true);
auto* access_type = auto access_type = ty.access(ast::AccessControl::kReadWrite, struct_type);
create<sem::AccessControl>(ast::AccessControl::kReadWrite, struct_type);
return {struct_type, std::move(access_type)}; return {struct_type, std::move(access_type)};
} }
@ -259,12 +255,11 @@ class InspectorHelper : public ProgramBuilder {
/// @returns a tuple {struct type, access control type}, where the struct has /// @returns a tuple {struct type, access control type}, where the struct has
/// the layout for a read-only storage buffer, and the control type /// the layout for a read-only storage buffer, and the control type
/// wraps the struct. /// wraps the struct.
std::tuple<sem::StructType*, sem::AccessControl*> std::tuple<typ::Struct, typ::AccessControl> MakeReadOnlyStorageBufferTypes(
MakeReadOnlyStorageBufferTypes(const std::string& name, const std::string& name,
std::vector<sem::Type*> member_types) { std::vector<typ::Type> member_types) {
auto* struct_type = MakeStructType(name, member_types, true); auto struct_type = MakeStructType(name, member_types, true);
auto* access_type = auto access_type = ty.access(ast::AccessControl::kReadOnly, struct_type);
create<sem::AccessControl>(ast::AccessControl::kReadOnly, struct_type);
return {struct_type, std::move(access_type)}; return {struct_type, std::move(access_type)};
} }
@ -275,7 +270,7 @@ class InspectorHelper : public ProgramBuilder {
/// @param group the binding and group to use for the uniform buffer /// @param group the binding and group to use for the uniform buffer
/// @param binding the binding number to use for the uniform buffer /// @param binding the binding number to use for the uniform buffer
void AddBinding(const std::string& name, void AddBinding(const std::string& name,
sem::Type* type, typ::Type type,
ast::StorageClass storage_class, ast::StorageClass storage_class,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
@ -292,7 +287,7 @@ class InspectorHelper : public ProgramBuilder {
/// @param group the binding/group/ to use for the uniform buffer /// @param group the binding/group/ to use for the uniform buffer
/// @param binding the binding number to use for the uniform buffer /// @param binding the binding number to use for the uniform buffer
void AddUniformBuffer(const std::string& name, void AddUniformBuffer(const std::string& name,
sem::Type* type, typ::Type type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kUniform, group, binding); AddBinding(name, type, ast::StorageClass::kUniform, group, binding);
@ -304,7 +299,7 @@ class InspectorHelper : public ProgramBuilder {
/// @param group the binding/group to use for the storage buffer /// @param group the binding/group to use for the storage buffer
/// @param binding the binding number to use for the storage buffer /// @param binding the binding number to use for the storage buffer
void AddStorageBuffer(const std::string& name, void AddStorageBuffer(const std::string& name,
sem::Type* type, typ::Type type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kStorage, group, binding); AddBinding(name, type, ast::StorageClass::kStorage, group, binding);
@ -317,11 +312,11 @@ class InspectorHelper : public ProgramBuilder {
void MakeStructVariableReferenceBodyFunction( void MakeStructVariableReferenceBodyFunction(
std::string func_name, std::string func_name,
std::string struct_name, std::string struct_name,
std::vector<std::tuple<size_t, sem::Type*>> members) { std::vector<std::tuple<size_t, typ::Type>> members) {
ast::StatementList stmts; ast::StatementList stmts;
for (auto member : members) { for (auto member : members) {
size_t member_idx; size_t member_idx;
sem::Type* member_type; typ::Type member_type;
std::tie(member_idx, member_type) = member; std::tie(member_idx, member_type) = member;
std::string member_name = StructMemberName(member_idx, member_type); std::string member_name = StructMemberName(member_idx, member_type);
@ -331,7 +326,7 @@ class InspectorHelper : public ProgramBuilder {
for (auto member : members) { for (auto member : members) {
size_t member_idx; size_t member_idx;
sem::Type* member_type; typ::Type member_type;
std::tie(member_idx, member_type) = member; std::tie(member_idx, member_type) = member;
std::string member_name = StructMemberName(member_idx, member_type); std::string member_name = StructMemberName(member_idx, member_type);
@ -369,26 +364,26 @@ class InspectorHelper : public ProgramBuilder {
/// @param dim the dimensions of the texture /// @param dim the dimensions of the texture
/// @param type the data type of the sampled texture /// @param type the data type of the sampled texture
/// @returns the generated SampleTextureType /// @returns the generated SampleTextureType
sem::SampledTexture* MakeSampledTextureType(ast::TextureDimension dim, typ::SampledTexture MakeSampledTextureType(ast::TextureDimension dim,
sem::Type* type) { typ::Type type) {
return create<sem::SampledTexture>(dim, type); return ty.sampled_texture(dim, type);
} }
/// Generates a DepthTexture appropriate for the params /// Generates a DepthTexture appropriate for the params
/// @param dim the dimensions of the texture /// @param dim the dimensions of the texture
/// @returns the generated DepthTexture /// @returns the generated DepthTexture
sem::DepthTexture* MakeDepthTextureType(ast::TextureDimension dim) { typ::DepthTexture MakeDepthTextureType(ast::TextureDimension dim) {
return create<sem::DepthTexture>(dim); return ty.depth_texture(dim);
} }
/// Generates a MultisampledTexture appropriate for the params /// Generates a MultisampledTexture appropriate for the params
/// @param dim the dimensions of the texture /// @param dim the dimensions of the texture
/// @param type the data type of the sampled texture /// @param type the data type of the sampled texture
/// @returns the generated SampleTextureType /// @returns the generated SampleTextureType
sem::MultisampledTexture* MakeMultisampledTextureType( typ::MultisampledTexture MakeMultisampledTextureType(
ast::TextureDimension dim, ast::TextureDimension dim,
sem::Type* type) { typ::Type type) {
return create<sem::MultisampledTexture>(dim, type); return ty.multisampled_texture(dim, type);
} }
/// Adds a sampled texture variable to the program /// Adds a sampled texture variable to the program
@ -397,7 +392,7 @@ class InspectorHelper : public ProgramBuilder {
/// @param group the binding/group to use for the sampled texture /// @param group the binding/group to use for the sampled texture
/// @param binding the binding number to use for the sampled texture /// @param binding the binding number to use for the sampled texture
void AddSampledTexture(const std::string& name, void AddSampledTexture(const std::string& name,
sem::Type* type, typ::Type type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kUniformConstant, group, binding); AddBinding(name, type, ast::StorageClass::kUniformConstant, group, binding);
@ -409,13 +404,13 @@ class InspectorHelper : public ProgramBuilder {
/// @param group the binding/group to use for the multi-sampled texture /// @param group the binding/group to use for the multi-sampled texture
/// @param binding the binding number to use for the multi-sampled texture /// @param binding the binding number to use for the multi-sampled texture
void AddMultisampledTexture(const std::string& name, void AddMultisampledTexture(const std::string& name,
sem::Type* type, typ::Type type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kUniformConstant, group, binding); AddBinding(name, type, ast::StorageClass::kUniformConstant, group, binding);
} }
void AddGlobalVariable(const std::string& name, sem::Type* type) { void AddGlobalVariable(const std::string& name, typ::Type type) {
Global(name, type, ast::StorageClass::kUniformConstant); Global(name, type, ast::StorageClass::kUniformConstant);
} }
@ -425,7 +420,7 @@ class InspectorHelper : public ProgramBuilder {
/// @param group the binding/group to use for the depth texture /// @param group the binding/group to use for the depth texture
/// @param binding the binding number to use for the depth texture /// @param binding the binding number to use for the depth texture
void AddDepthTexture(const std::string& name, void AddDepthTexture(const std::string& name,
sem::Type* type, typ::Type type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kUniformConstant, group, binding); AddBinding(name, type, ast::StorageClass::kUniformConstant, group, binding);
@ -444,12 +439,12 @@ class InspectorHelper : public ProgramBuilder {
const std::string& texture_name, const std::string& texture_name,
const std::string& sampler_name, const std::string& sampler_name,
const std::string& coords_name, const std::string& coords_name,
sem::Type* base_type, typ::Type base_type,
ast::DecorationList decorations) { ast::DecorationList decorations) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
ast::StatementList stmts; ast::StatementList stmts;
stmts.emplace_back(Decl(Var("sampler_result", vec_type(base_type, 4), stmts.emplace_back(Decl(Var("sampler_result", ty.vec(base_type, 4),
ast::StorageClass::kFunction))); ast::StorageClass::kFunction)));
stmts.emplace_back( stmts.emplace_back(
@ -475,13 +470,13 @@ class InspectorHelper : public ProgramBuilder {
const std::string& sampler_name, const std::string& sampler_name,
const std::string& coords_name, const std::string& coords_name,
const std::string& array_index, const std::string& array_index,
sem::Type* base_type, typ::Type base_type,
ast::DecorationList decorations) { ast::DecorationList decorations) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
ast::StatementList stmts; ast::StatementList stmts;
stmts.emplace_back(Decl(Var("sampler_result", vec_type(base_type, 4), stmts.emplace_back(Decl(Var("sampler_result", ty.vec(base_type, 4),
ast::StorageClass::kFunction))); ast::StorageClass::kFunction)));
stmts.emplace_back( stmts.emplace_back(
@ -508,7 +503,7 @@ class InspectorHelper : public ProgramBuilder {
const std::string& sampler_name, const std::string& sampler_name,
const std::string& coords_name, const std::string& coords_name,
const std::string& depth_name, const std::string& depth_name,
sem::Type* base_type, typ::Type base_type,
ast::DecorationList decorations) { ast::DecorationList decorations) {
std::string result_name = "sampler_result"; std::string result_name = "sampler_result";
@ -527,7 +522,7 @@ class InspectorHelper : public ProgramBuilder {
/// Gets an appropriate type for the data in a given texture type. /// Gets an appropriate type for the data in a given texture type.
/// @param sampled_kind type of in the texture /// @param sampled_kind type of in the texture
/// @returns a pointer to a type appropriate for the coord param /// @returns a pointer to a type appropriate for the coord param
sem::Type* GetBaseType(ResourceBinding::SampledKind sampled_kind) { typ::Type GetBaseType(ResourceBinding::SampledKind sampled_kind) {
switch (sampled_kind) { switch (sampled_kind) {
case ResourceBinding::SampledKind::kFloat: case ResourceBinding::SampledKind::kFloat:
return ty.f32(); return ty.f32();
@ -545,7 +540,7 @@ class InspectorHelper : public ProgramBuilder {
/// @param dim dimensionality of the texture being sampled /// @param dim dimensionality of the texture being sampled
/// @param scalar the scalar type /// @param scalar the scalar type
/// @returns a pointer to a type appropriate for the coord param /// @returns a pointer to a type appropriate for the coord param
sem::Type* GetCoordsType(ast::TextureDimension dim, sem::Type* scalar) { typ::Type GetCoordsType(ast::TextureDimension dim, typ::Type scalar) {
switch (dim) { switch (dim) {
case ast::TextureDimension::k1d: case ast::TextureDimension::k1d:
return scalar; return scalar;
@ -566,11 +561,11 @@ class InspectorHelper : public ProgramBuilder {
/// @param dim the texture dimension of the storage texture /// @param dim the texture dimension of the storage texture
/// @param format the image format of the storage texture /// @param format the image format of the storage texture
/// @returns the storage texture type and subtype /// @returns the storage texture type and subtype
std::tuple<sem::StorageTexture*, sem::Type*> MakeStorageTextureTypes( std::tuple<typ::StorageTexture, typ::Type> MakeStorageTextureTypes(
ast::TextureDimension dim, ast::TextureDimension dim,
ast::ImageFormat format) { ast::ImageFormat format) {
sem::Type* subtype = sem::StorageTexture::SubtypeFor(format, Types()); auto tex = ty.storage_texture(dim, format);
return {create<sem::StorageTexture>(dim, format, subtype), subtype}; return {tex, {tex.ast->type(), tex.sem->type()}};
} }
/// Generates appropriate types for a Read-Only StorageTexture /// Generates appropriate types for a Read-Only StorageTexture
@ -578,15 +573,14 @@ class InspectorHelper : public ProgramBuilder {
/// @param format the image format of the storage texture /// @param format the image format of the storage texture
/// @param read_only should the access type be read only, otherwise write only /// @param read_only should the access type be read only, otherwise write only
/// @returns the storage texture type, subtype & access control type /// @returns the storage texture type, subtype & access control type
std::tuple<sem::StorageTexture*, sem::Type*, sem::AccessControl*> std::tuple<typ::StorageTexture, typ::Type, typ::AccessControl>
MakeStorageTextureTypes(ast::TextureDimension dim, MakeStorageTextureTypes(ast::TextureDimension dim,
ast::ImageFormat format, ast::ImageFormat format,
bool read_only) { bool read_only) {
sem::StorageTexture* texture_type; typ::StorageTexture texture_type;
sem::Type* subtype; typ::Type subtype;
std::tie(texture_type, subtype) = MakeStorageTextureTypes(dim, format); std::tie(texture_type, subtype) = MakeStorageTextureTypes(dim, format);
auto* access_control = auto access_control = ty.access(read_only ? ast::AccessControl::kReadOnly
create<sem::AccessControl>(read_only ? ast::AccessControl::kReadOnly
: ast::AccessControl::kWriteOnly, : ast::AccessControl::kWriteOnly,
texture_type); texture_type);
return {texture_type, subtype, access_control}; return {texture_type, subtype, access_control};
@ -598,7 +592,7 @@ class InspectorHelper : public ProgramBuilder {
/// @param group the binding/group to use for the sampled texture /// @param group the binding/group to use for the sampled texture
/// @param binding the binding number to use for the sampled texture /// @param binding the binding number to use for the sampled texture
void AddStorageTexture(const std::string& name, void AddStorageTexture(const std::string& name,
sem::Type* type, typ::Type type,
uint32_t group, uint32_t group,
uint32_t binding) { uint32_t binding) {
AddBinding(name, type, ast::StorageClass::kUniformConstant, group, binding); AddBinding(name, type, ast::StorageClass::kUniformConstant, group, binding);
@ -613,7 +607,7 @@ class InspectorHelper : public ProgramBuilder {
ast::Function* MakeStorageTextureBodyFunction( ast::Function* MakeStorageTextureBodyFunction(
const std::string& func_name, const std::string& func_name,
const std::string& st_name, const std::string& st_name,
sem::Type* dim_type, typ::Type dim_type,
ast::DecorationList decorations) { ast::DecorationList decorations) {
ast::StatementList stmts; ast::StatementList stmts;
@ -638,34 +632,14 @@ class InspectorHelper : public ProgramBuilder {
return *inspector_; return *inspector_;
} }
sem::ArrayType* u32_array_type(uint32_t count) { typ::Sampler sampler_type() { return ty.sampler(ast::SamplerKind::kSampler); }
if (array_type_memo_.find(count) == array_type_memo_.end()) { typ::Sampler comparison_sampler_type() {
array_type_memo_[count] = return ty.sampler(ast::SamplerKind::kComparisonSampler);
create<sem::ArrayType>(ty.u32(), count,
ast::DecorationList{
create<ast::StrideDecoration>(4),
});
} }
return array_type_memo_[count];
}
sem::Vector* vec_type(sem::Type* type, uint32_t count) {
if (vector_type_memo_.find(std::tie(type, count)) ==
vector_type_memo_.end()) {
vector_type_memo_[std::tie(type, count)] =
create<sem::Vector>(type, count);
}
return vector_type_memo_[std::tie(type, count)];
}
sem::Sampler* sampler_type() { return &sampler_type_; }
sem::Sampler* comparison_sampler_type() { return &comparison_sampler_type_; }
private: private:
std::unique_ptr<Program> program_; std::unique_ptr<Program> program_;
std::unique_ptr<Inspector> inspector_; std::unique_ptr<Inspector> inspector_;
sem::Sampler sampler_type_;
sem::Sampler comparison_sampler_type_;
std::map<uint32_t, sem::ArrayType*> array_type_memo_;
std::map<std::tuple<sem::Type*, uint32_t>, sem::Vector*> vector_type_memo_;
}; };
class InspectorGetEntryPointTest : public InspectorHelper, class InspectorGetEntryPointTest : public InspectorHelper,
@ -889,7 +863,7 @@ TEST_F(InspectorGetEntryPointTest, NoInOutVariables) {
TEST_P(InspectorGetEntryPointTestWithComponentTypeParam, InOutVariables) { TEST_P(InspectorGetEntryPointTestWithComponentTypeParam, InOutVariables) {
ComponentType inspector_type = GetParam(); ComponentType inspector_type = GetParam();
sem::Type* tint_type = nullptr; typ::Type tint_type = nullptr;
switch (inspector_type) { switch (inspector_type) {
case ComponentType::kFloat: case ComponentType::kFloat:
tint_type = ty.f32(); tint_type = ty.f32();
@ -1031,7 +1005,7 @@ TEST_F(InspectorGetEntryPointTest, BuiltInsNotStageVariables) {
} }
TEST_F(InspectorGetEntryPointTest, InOutStruct) { TEST_F(InspectorGetEntryPointTest, InOutStruct) {
auto* interface = MakeInOutStruct("interface", {{"a", 0u}, {"b", 1u}}); auto interface = MakeInOutStruct("interface", {{"a", 0u}, {"b", 1u}});
Func("foo", {Param("param", interface)}, interface, {Return("param")}, Func("foo", {Param("param", interface)}, interface, {Return("param")},
{Stage(ast::PipelineStage::kFragment)}); {Stage(ast::PipelineStage::kFragment)});
Inspector& inspector = Build(); Inspector& inspector = Build();
@ -1063,7 +1037,7 @@ TEST_F(InspectorGetEntryPointTest, InOutStruct) {
} }
TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutSharedStruct) { TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutSharedStruct) {
auto* interface = MakeInOutStruct("interface", {{"a", 0u}, {"b", 1u}}); auto interface = MakeInOutStruct("interface", {{"a", 0u}, {"b", 1u}});
Func("foo", {}, interface, {Return(Construct(interface))}, Func("foo", {}, interface, {Return(Construct(interface))},
{Stage(ast::PipelineStage::kFragment)}); {Stage(ast::PipelineStage::kFragment)});
Func("bar", {Param("param", interface)}, ty.void_(), {}, Func("bar", {Param("param", interface)}, ty.void_(), {},
@ -1101,8 +1075,8 @@ TEST_F(InspectorGetEntryPointTest, MultipleEntryPointsInOutSharedStruct) {
} }
TEST_F(InspectorGetEntryPointTest, MixInOutVariablesAndStruct) { TEST_F(InspectorGetEntryPointTest, MixInOutVariablesAndStruct) {
auto* struct_a = MakeInOutStruct("struct_a", {{"a", 0u}, {"b", 1u}}); auto struct_a = MakeInOutStruct("struct_a", {{"a", 0u}, {"b", 1u}});
auto* struct_b = MakeInOutStruct("struct_b", {{"a", 2u}}); auto struct_b = MakeInOutStruct("struct_b", {{"a", 2u}});
Func("foo", Func("foo",
{Param("param_a", struct_a), Param("param_b", struct_b), {Param("param_a", struct_a), Param("param_b", struct_b),
Param("param_c", ty.f32(), {Location(3u)}), Param("param_c", ty.f32(), {Location(3u)}),
@ -1650,27 +1624,26 @@ TEST_F(InspectorGetResourceBindingsTest, Empty) {
} }
TEST_F(InspectorGetResourceBindingsTest, Simple) { TEST_F(InspectorGetResourceBindingsTest, Simple) {
sem::StructType* ub_struct_type = typ::Struct ub_struct_type = MakeUniformBufferType("ub_type", {ty.i32()});
MakeUniformBufferType("ub_type", {ty.i32()});
AddUniformBuffer("ub_var", ub_struct_type, 0, 0); AddUniformBuffer("ub_var", ub_struct_type, 0, 0);
MakeStructVariableReferenceBodyFunction("ub_func", "ub_var", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("ub_func", "ub_var", {{0, ty.i32()}});
sem::StructType* sb_struct_type; typ::Struct sb_struct_type;
sem::AccessControl* sb_control_type; typ::AccessControl sb_control_type;
std::tie(sb_struct_type, sb_control_type) = std::tie(sb_struct_type, sb_control_type) =
MakeStorageBufferTypes("sb_type", {ty.i32()}); MakeStorageBufferTypes("sb_type", {ty.i32()});
AddStorageBuffer("sb_var", sb_control_type, 1, 0); AddStorageBuffer("sb_var", sb_control_type, 1, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "sb_var", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "sb_var", {{0, ty.i32()}});
sem::StructType* rosb_struct_type; typ::Struct rosb_struct_type;
sem::AccessControl* rosb_control_type; typ::AccessControl rosb_control_type;
std::tie(rosb_struct_type, rosb_control_type) = std::tie(rosb_struct_type, rosb_control_type) =
MakeReadOnlyStorageBufferTypes("rosb_type", {ty.i32()}); MakeReadOnlyStorageBufferTypes("rosb_type", {ty.i32()});
AddStorageBuffer("rosb_var", rosb_control_type, 1, 1); AddStorageBuffer("rosb_var", rosb_control_type, 1, 1);
MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var", MakeStructVariableReferenceBodyFunction("rosb_func", "rosb_var",
{{0, ty.i32()}}); {{0, ty.i32()}});
auto* s_texture_type = auto s_texture_type =
MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32()); MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32());
AddSampledTexture("s_texture", s_texture_type, 2, 0); AddSampledTexture("s_texture", s_texture_type, 2, 0);
AddSampler("s_var", 3, 0); AddSampler("s_var", 3, 0);
@ -1678,8 +1651,7 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
MakeSamplerReferenceBodyFunction("s_func", "s_texture", "s_var", "s_coords", MakeSamplerReferenceBodyFunction("s_func", "s_texture", "s_var", "s_coords",
ty.f32(), {}); ty.f32(), {});
auto* cs_depth_texture_type = auto cs_depth_texture_type = MakeDepthTextureType(ast::TextureDimension::k2d);
MakeDepthTextureType(ast::TextureDimension::k2d);
AddDepthTexture("cs_texture", cs_depth_texture_type, 3, 1); AddDepthTexture("cs_texture", cs_depth_texture_type, 3, 1);
AddComparisonSampler("cs_var", 3, 2); AddComparisonSampler("cs_var", 3, 2);
AddGlobalVariable("cs_coords", ty.vec2<f32>()); AddGlobalVariable("cs_coords", ty.vec2<f32>());
@ -1687,17 +1659,17 @@ TEST_F(InspectorGetResourceBindingsTest, Simple) {
MakeComparisonSamplerReferenceBodyFunction( MakeComparisonSamplerReferenceBodyFunction(
"cs_func", "cs_texture", "cs_var", "cs_coords", "cs_depth", ty.f32(), {}); "cs_func", "cs_texture", "cs_var", "cs_coords", "cs_depth", ty.f32(), {});
sem::StorageTexture* st_type; typ::StorageTexture st_type;
sem::Type* st_subtype; typ::Type st_subtype;
sem::AccessControl* st_ac; typ::AccessControl st_ac;
std::tie(st_type, st_subtype, st_ac) = MakeStorageTextureTypes( std::tie(st_type, st_subtype, st_ac) = MakeStorageTextureTypes(
ast::TextureDimension::k2d, ast::ImageFormat::kR32Uint, false); ast::TextureDimension::k2d, ast::ImageFormat::kR32Uint, false);
AddStorageTexture("st_var", st_ac, 4, 0); AddStorageTexture("st_var", st_ac, 4, 0);
MakeStorageTextureBodyFunction("st_func", "st_var", ty.vec2<i32>(), {}); MakeStorageTextureBodyFunction("st_func", "st_var", ty.vec2<i32>(), {});
sem::StorageTexture* rost_type; typ::StorageTexture rost_type;
sem::Type* rost_subtype; typ::Type rost_subtype;
sem::AccessControl* rost_ac; typ::AccessControl rost_ac;
std::tie(rost_type, rost_subtype, rost_ac) = MakeStorageTextureTypes( std::tie(rost_type, rost_subtype, rost_ac) = MakeStorageTextureTypes(
ast::TextureDimension::k2d, ast::ImageFormat::kR32Uint, true); ast::TextureDimension::k2d, ast::ImageFormat::kR32Uint, true);
AddStorageTexture("rost_var", rost_ac, 4, 1); AddStorageTexture("rost_var", rost_ac, 4, 1);
@ -1771,8 +1743,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MissingEntryPoint) {
} }
TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonEntryPointFunc) { TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonEntryPointFunc) {
sem::StructType* foo_struct_type = typ::Struct foo_struct_type = MakeUniformBufferType("foo_type", {ty.i32()});
MakeUniformBufferType("foo_type", {ty.i32()});
AddUniformBuffer("foo_ub", foo_struct_type, 0, 0); AddUniformBuffer("foo_ub", foo_struct_type, 0, 0);
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
@ -1790,8 +1761,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, NonEntryPointFunc) {
} }
TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple) { TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple) {
sem::StructType* foo_struct_type = typ::Struct foo_struct_type = MakeUniformBufferType("foo_type", {ty.i32()});
MakeUniformBufferType("foo_type", {ty.i32()});
AddUniformBuffer("foo_ub", foo_struct_type, 0, 0); AddUniformBuffer("foo_ub", foo_struct_type, 0, 0);
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
@ -1816,7 +1786,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, Simple) {
} }
TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleMembers) { TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleMembers) {
sem::StructType* foo_struct_type = typ::Struct foo_struct_type =
MakeUniformBufferType("foo_type", {ty.i32(), ty.u32(), ty.f32()}); MakeUniformBufferType("foo_type", {ty.i32(), ty.u32(), ty.f32()});
AddUniformBuffer("foo_ub", foo_struct_type, 0, 0); AddUniformBuffer("foo_ub", foo_struct_type, 0, 0);
@ -1843,7 +1813,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleMembers) {
} }
TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingPadding) { TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingPadding) {
sem::StructType* foo_struct_type = typ::Struct foo_struct_type =
MakeUniformBufferType("foo_type", {ty.vec3<f32>()}); MakeUniformBufferType("foo_type", {ty.vec3<f32>()});
AddUniformBuffer("foo_ub", foo_struct_type, 0, 0); AddUniformBuffer("foo_ub", foo_struct_type, 0, 0);
@ -1870,7 +1840,7 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingPadding) {
} }
TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) { TEST_F(InspectorGetUniformBufferResourceBindingsTest, MultipleUniformBuffers) {
sem::StructType* ub_struct_type = typ::Struct ub_struct_type =
MakeUniformBufferType("ub_type", {ty.i32(), ty.u32(), ty.f32()}); MakeUniformBufferType("ub_type", {ty.i32(), ty.u32(), ty.f32()});
AddUniformBuffer("ub_foo", ub_struct_type, 0, 0); AddUniformBuffer("ub_foo", ub_struct_type, 0, 0);
AddUniformBuffer("ub_bar", ub_struct_type, 0, 1); AddUniformBuffer("ub_bar", ub_struct_type, 0, 1);
@ -1928,8 +1898,8 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingArray) {
// TODO(bclayton) - This is not a legal structure layout for uniform buffer // TODO(bclayton) - This is not a legal structure layout for uniform buffer
// usage. Once crbug.com/tint/628 is implemented, this will fail validation // usage. Once crbug.com/tint/628 is implemented, this will fail validation
// and will need to be fixed. // and will need to be fixed.
sem::StructType* foo_struct_type = typ::Struct foo_struct_type =
MakeUniformBufferType("foo_type", {ty.i32(), u32_array_type(4)}); MakeUniformBufferType("foo_type", {ty.i32(), ty.array<u32, 4>()});
AddUniformBuffer("foo_ub", foo_struct_type, 0, 0); AddUniformBuffer("foo_ub", foo_struct_type, 0, 0);
MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("ub_func", "foo_ub", {{0, ty.i32()}});
@ -1954,8 +1924,8 @@ TEST_F(InspectorGetUniformBufferResourceBindingsTest, ContainingArray) {
} }
TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) =
MakeStorageBufferTypes("foo_type", {ty.i32()}); MakeStorageBufferTypes("foo_type", {ty.i32()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
@ -1982,8 +1952,8 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, Simple) {
} }
TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) =
MakeStorageBufferTypes("foo_type", {ty.i32(), ty.u32(), ty.f32()}); MakeStorageBufferTypes("foo_type", {ty.i32(), ty.u32(), ty.f32()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
@ -2011,8 +1981,8 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleMembers) {
} }
TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
sem::StructType* sb_struct_type; typ::Struct sb_struct_type;
sem::AccessControl* sb_control_type; typ::AccessControl sb_control_type;
std::tie(sb_struct_type, sb_control_type) = std::tie(sb_struct_type, sb_control_type) =
MakeStorageBufferTypes("sb_type", {ty.i32(), ty.u32(), ty.f32()}); MakeStorageBufferTypes("sb_type", {ty.i32(), ty.u32(), ty.f32()});
AddStorageBuffer("sb_foo", sb_control_type, 0, 0); AddStorageBuffer("sb_foo", sb_control_type, 0, 0);
@ -2072,10 +2042,10 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, MultipleStorageBuffers) {
} }
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) =
MakeStorageBufferTypes("foo_type", {ty.i32(), u32_array_type(4)}); MakeStorageBufferTypes("foo_type", {ty.i32(), ty.array<u32, 4>()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2100,10 +2070,10 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingArray) {
} }
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) =
MakeStorageBufferTypes("foo_type", {ty.i32(), u32_array_type(0)}); MakeStorageBufferTypes("foo_type", {ty.i32(), ty.array<u32>()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2128,8 +2098,8 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingRuntimeArray) {
} }
TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) =
MakeStorageBufferTypes("foo_type", {ty.vec3<f32>()}); MakeStorageBufferTypes("foo_type", {ty.vec3<f32>()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
@ -2157,8 +2127,8 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, ContainingPadding) {
} }
TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) { TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) =
MakeReadOnlyStorageBufferTypes("foo_type", {ty.i32()}); MakeReadOnlyStorageBufferTypes("foo_type", {ty.i32()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
@ -2178,8 +2148,8 @@ TEST_F(InspectorGetStorageBufferResourceBindingsTest, SkipReadOnly) {
} }
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) { TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) =
MakeReadOnlyStorageBufferTypes("foo_type", {ty.i32()}); MakeReadOnlyStorageBufferTypes("foo_type", {ty.i32()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
@ -2207,8 +2177,8 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, Simple) {
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
MultipleStorageBuffers) { MultipleStorageBuffers) {
sem::StructType* sb_struct_type; typ::Struct sb_struct_type;
sem::AccessControl* sb_control_type; typ::AccessControl sb_control_type;
std::tie(sb_struct_type, sb_control_type) = std::tie(sb_struct_type, sb_control_type) =
MakeReadOnlyStorageBufferTypes("sb_type", {ty.i32(), ty.u32(), ty.f32()}); MakeReadOnlyStorageBufferTypes("sb_type", {ty.i32(), ty.u32(), ty.f32()});
AddStorageBuffer("sb_foo", sb_control_type, 0, 0); AddStorageBuffer("sb_foo", sb_control_type, 0, 0);
@ -2268,10 +2238,10 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
} }
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) { TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) = MakeReadOnlyStorageBufferTypes(
MakeReadOnlyStorageBufferTypes("foo_type", {ty.i32(), u32_array_type(4)}); "foo_type", {ty.i32(), ty.array<u32, 4>()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2297,10 +2267,10 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, ContainingArray) {
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
ContainingRuntimeArray) { ContainingRuntimeArray) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) =
MakeReadOnlyStorageBufferTypes("foo_type", {ty.i32(), u32_array_type(0)}); MakeReadOnlyStorageBufferTypes("foo_type", {ty.i32(), ty.array<u32>()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}}); MakeStructVariableReferenceBodyFunction("sb_func", "foo_sb", {{0, ty.i32()}});
@ -2325,8 +2295,8 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest,
} }
TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) { TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
sem::StructType* foo_struct_type; typ::Struct foo_struct_type;
sem::AccessControl* foo_control_type; typ::AccessControl foo_control_type;
std::tie(foo_struct_type, foo_control_type) = std::tie(foo_struct_type, foo_control_type) =
MakeStorageBufferTypes("foo_type", {ty.i32()}); MakeStorageBufferTypes("foo_type", {ty.i32()});
AddStorageBuffer("foo_sb", foo_control_type, 0, 0); AddStorageBuffer("foo_sb", foo_control_type, 0, 0);
@ -2346,7 +2316,7 @@ TEST_F(InspectorGetReadOnlyStorageBufferResourceBindingsTest, SkipNonReadOnly) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) { TEST_F(InspectorGetSamplerResourceBindingsTest, Simple) {
auto* sampled_texture_type = auto sampled_texture_type =
MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32()); MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32());
AddSampledTexture("foo_texture", sampled_texture_type, 0, 0); AddSampledTexture("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
@ -2383,7 +2353,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, NoSampler) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) { TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
auto* sampled_texture_type = auto sampled_texture_type =
MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32()); MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32());
AddSampledTexture("foo_texture", sampled_texture_type, 0, 0); AddSampledTexture("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
@ -2409,7 +2379,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, InFunction) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) { TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
auto* sampled_texture_type = auto sampled_texture_type =
MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32()); MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32());
AddSampledTexture("foo_texture", sampled_texture_type, 0, 0); AddSampledTexture("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
@ -2428,7 +2398,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, UnknownEntryPoint) {
} }
TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) { TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
auto* depth_texture_type = MakeDepthTextureType(ast::TextureDimension::k2d); auto depth_texture_type = MakeDepthTextureType(ast::TextureDimension::k2d);
AddDepthTexture("foo_texture", depth_texture_type, 0, 0); AddDepthTexture("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1); AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>()); AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2449,7 +2419,7 @@ TEST_F(InspectorGetSamplerResourceBindingsTest, SkipsComparisonSamplers) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) { TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, Simple) {
auto* depth_texture_type = MakeDepthTextureType(ast::TextureDimension::k2d); auto depth_texture_type = MakeDepthTextureType(ast::TextureDimension::k2d);
AddDepthTexture("foo_texture", depth_texture_type, 0, 0); AddDepthTexture("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1); AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>()); AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2487,7 +2457,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, NoSampler) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) { TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
auto* depth_texture_type = MakeDepthTextureType(ast::TextureDimension::k2d); auto depth_texture_type = MakeDepthTextureType(ast::TextureDimension::k2d);
AddDepthTexture("foo_texture", depth_texture_type, 0, 0); AddDepthTexture("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1); AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>()); AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2515,7 +2485,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, InFunction) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) { TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
auto* depth_texture_type = MakeDepthTextureType(ast::TextureDimension::k2d); auto depth_texture_type = MakeDepthTextureType(ast::TextureDimension::k2d);
AddDepthTexture("foo_texture", depth_texture_type, 0, 0); AddDepthTexture("foo_texture", depth_texture_type, 0, 0);
AddComparisonSampler("foo_sampler", 0, 1); AddComparisonSampler("foo_sampler", 0, 1);
AddGlobalVariable("foo_coords", ty.vec2<f32>()); AddGlobalVariable("foo_coords", ty.vec2<f32>());
@ -2534,7 +2504,7 @@ TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, UnknownEntryPoint) {
} }
TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) { TEST_F(InspectorGetComparisonSamplerResourceBindingsTest, SkipsSamplers) {
auto* sampled_texture_type = auto sampled_texture_type =
MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32()); MakeSampledTextureType(ast::TextureDimension::k1d, ty.f32());
AddSampledTexture("foo_texture", sampled_texture_type, 0, 0); AddSampledTexture("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
@ -2568,11 +2538,11 @@ TEST_F(InspectorGetSampledTextureResourceBindingsTest, Empty) {
} }
TEST_P(InspectorGetSampledTextureResourceBindingsTestWithParam, textureSample) { TEST_P(InspectorGetSampledTextureResourceBindingsTestWithParam, textureSample) {
auto* sampled_texture_type = MakeSampledTextureType( auto sampled_texture_type = MakeSampledTextureType(
GetParam().type_dim, GetBaseType(GetParam().sampled_kind)); GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddSampledTexture("foo_texture", sampled_texture_type, 0, 0); AddSampledTexture("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
auto* coord_type = GetCoordsType(GetParam().type_dim, ty.f32()); auto coord_type = GetCoordsType(GetParam().type_dim, ty.f32());
AddGlobalVariable("foo_coords", coord_type); AddGlobalVariable("foo_coords", coord_type);
MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler", MakeSamplerReferenceBodyFunction("ep", "foo_texture", "foo_sampler",
@ -2626,11 +2596,11 @@ INSTANTIATE_TEST_SUITE_P(
TEST_P(InspectorGetSampledArrayTextureResourceBindingsTestWithParam, TEST_P(InspectorGetSampledArrayTextureResourceBindingsTestWithParam,
textureSample) { textureSample) {
auto* sampled_texture_type = MakeSampledTextureType( auto sampled_texture_type = MakeSampledTextureType(
GetParam().type_dim, GetBaseType(GetParam().sampled_kind)); GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddSampledTexture("foo_texture", sampled_texture_type, 0, 0); AddSampledTexture("foo_texture", sampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
auto* coord_type = GetCoordsType(GetParam().type_dim, ty.f32()); auto coord_type = GetCoordsType(GetParam().type_dim, ty.f32());
AddGlobalVariable("foo_coords", coord_type); AddGlobalVariable("foo_coords", coord_type);
AddGlobalVariable("foo_array_index", ty.i32()); AddGlobalVariable("foo_array_index", ty.i32());
@ -2670,10 +2640,10 @@ INSTANTIATE_TEST_SUITE_P(
TEST_P(InspectorGetMultisampledTextureResourceBindingsTestWithParam, TEST_P(InspectorGetMultisampledTextureResourceBindingsTestWithParam,
textureLoad) { textureLoad) {
auto* multisampled_texture_type = MakeMultisampledTextureType( auto multisampled_texture_type = MakeMultisampledTextureType(
GetParam().type_dim, GetBaseType(GetParam().sampled_kind)); GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddMultisampledTexture("foo_texture", multisampled_texture_type, 0, 0); AddMultisampledTexture("foo_texture", multisampled_texture_type, 0, 0);
auto* coord_type = GetCoordsType(GetParam().type_dim, ty.i32()); auto coord_type = GetCoordsType(GetParam().type_dim, ty.i32());
AddGlobalVariable("foo_coords", coord_type); AddGlobalVariable("foo_coords", coord_type);
AddGlobalVariable("foo_sample_index", ty.i32()); AddGlobalVariable("foo_sample_index", ty.i32());
@ -2739,11 +2709,11 @@ TEST_F(InspectorGetMultisampledArrayTextureResourceBindingsTest, Empty) {
TEST_P(InspectorGetMultisampledArrayTextureResourceBindingsTestWithParam, TEST_P(InspectorGetMultisampledArrayTextureResourceBindingsTestWithParam,
DISABLED_textureSample) { DISABLED_textureSample) {
auto* multisampled_texture_type = MakeMultisampledTextureType( auto multisampled_texture_type = MakeMultisampledTextureType(
GetParam().type_dim, GetBaseType(GetParam().sampled_kind)); GetParam().type_dim, GetBaseType(GetParam().sampled_kind));
AddMultisampledTexture("foo_texture", multisampled_texture_type, 0, 0); AddMultisampledTexture("foo_texture", multisampled_texture_type, 0, 0);
AddSampler("foo_sampler", 0, 1); AddSampler("foo_sampler", 0, 1);
auto* coord_type = GetCoordsType(GetParam().type_dim, ty.f32()); auto coord_type = GetCoordsType(GetParam().type_dim, ty.f32());
AddGlobalVariable("foo_coords", coord_type); AddGlobalVariable("foo_coords", coord_type);
AddGlobalVariable("foo_array_index", ty.i32()); AddGlobalVariable("foo_array_index", ty.i32());
@ -2816,14 +2786,14 @@ TEST_P(InspectorGetStorageTextureResourceBindingsTestWithParam, Simple) {
ResourceBinding::SampledKind expected_kind; ResourceBinding::SampledKind expected_kind;
std::tie(format, expected_format, expected_kind) = format_params; std::tie(format, expected_format, expected_kind) = format_params;
sem::StorageTexture* st_type; typ::StorageTexture st_type;
sem::Type* st_subtype; typ::Type st_subtype;
sem::AccessControl* ac; typ::AccessControl ac;
std::tie(st_type, st_subtype, ac) = std::tie(st_type, st_subtype, ac) =
MakeStorageTextureTypes(dim, format, read_only); MakeStorageTextureTypes(dim, format, read_only);
AddStorageTexture("st_var", ac, 0, 0); AddStorageTexture("st_var", ac, 0, 0);
sem::Type* dim_type = nullptr; typ::Type dim_type = nullptr;
switch (dim) { switch (dim) {
case ast::TextureDimension::k1d: case ast::TextureDimension::k1d:
dim_type = ty.i32(); dim_type = ty.i32();
@ -2935,7 +2905,7 @@ INSTANTIATE_TEST_SUITE_P(
TEST_P(InspectorGetDepthTextureResourceBindingsTestWithParam, TEST_P(InspectorGetDepthTextureResourceBindingsTestWithParam,
textureDimensions) { textureDimensions) {
auto* depth_texture_type = MakeDepthTextureType(GetParam().type_dim); auto depth_texture_type = MakeDepthTextureType(GetParam().type_dim);
AddDepthTexture("dt", depth_texture_type, 0, 0); AddDepthTexture("dt", depth_texture_type, 0, 0);
AddGlobalVariable("dt_level", ty.i32()); AddGlobalVariable("dt_level", ty.i32());

View File

@ -69,7 +69,7 @@ TEST_F(IntrinsicTableTest, MismatchU32) {
} }
TEST_F(IntrinsicTableTest, MatchI32) { TEST_F(IntrinsicTableTest, MatchI32) {
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k1d, ty.f32()); auto tex = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
auto result = table->Lookup(*this, IntrinsicType::kTextureLoad, auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
{tex, ty.i32(), ty.i32()}, Source{}); {tex, ty.i32(), ty.i32()}, Source{});
ASSERT_NE(result.intrinsic, nullptr); ASSERT_NE(result.intrinsic, nullptr);
@ -83,7 +83,7 @@ TEST_F(IntrinsicTableTest, MatchI32) {
} }
TEST_F(IntrinsicTableTest, MismatchI32) { TEST_F(IntrinsicTableTest, MismatchI32) {
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k1d, ty.f32()); auto tex = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
auto result = table->Lookup(*this, IntrinsicType::kTextureLoad, auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
{tex, ty.f32()}, Source{}); {tex, ty.f32()}, Source{});
ASSERT_EQ(result.intrinsic, nullptr); ASSERT_EQ(result.intrinsic, nullptr);
@ -219,8 +219,8 @@ TEST_F(IntrinsicTableTest, MismatchArray) {
} }
TEST_F(IntrinsicTableTest, MatchSampler) { TEST_F(IntrinsicTableTest, MatchSampler) {
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k2d, ty.f32()); auto tex = ty.sampled_texture(ast::TextureDimension::k2d, ty.f32());
auto* sampler = create<sem::Sampler>(ast::SamplerKind::kSampler); auto sampler = ty.sampler(ast::SamplerKind::kSampler);
auto result = table->Lookup(*this, IntrinsicType::kTextureSample, auto result = table->Lookup(*this, IntrinsicType::kTextureSample,
{tex, sampler, ty.vec2<f32>()}, Source{}); {tex, sampler, ty.vec2<f32>()}, Source{});
ASSERT_NE(result.intrinsic, nullptr); ASSERT_NE(result.intrinsic, nullptr);
@ -235,7 +235,7 @@ TEST_F(IntrinsicTableTest, MatchSampler) {
} }
TEST_F(IntrinsicTableTest, MismatchSampler) { TEST_F(IntrinsicTableTest, MismatchSampler) {
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k2d, ty.f32()); auto tex = ty.sampled_texture(ast::TextureDimension::k2d, ty.f32());
auto result = table->Lookup(*this, IntrinsicType::kTextureSample, auto result = table->Lookup(*this, IntrinsicType::kTextureSample,
{tex, ty.f32(), ty.vec2<f32>()}, Source{}); {tex, ty.f32(), ty.vec2<f32>()}, Source{});
ASSERT_EQ(result.intrinsic, nullptr); ASSERT_EQ(result.intrinsic, nullptr);
@ -243,7 +243,7 @@ TEST_F(IntrinsicTableTest, MismatchSampler) {
} }
TEST_F(IntrinsicTableTest, MatchSampledTexture) { TEST_F(IntrinsicTableTest, MatchSampledTexture) {
auto* tex = create<sem::SampledTexture>(ast::TextureDimension::k2d, ty.f32()); auto tex = ty.sampled_texture(ast::TextureDimension::k2d, ty.f32());
auto result = table->Lookup(*this, IntrinsicType::kTextureLoad, auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
{tex, ty.vec2<i32>(), ty.i32()}, Source{}); {tex, ty.vec2<i32>(), ty.i32()}, Source{});
ASSERT_NE(result.intrinsic, nullptr); ASSERT_NE(result.intrinsic, nullptr);
@ -272,7 +272,7 @@ TEST_F(IntrinsicTableTest, MatchMultisampledTexture) {
} }
TEST_F(IntrinsicTableTest, MatchDepthTexture) { TEST_F(IntrinsicTableTest, MatchDepthTexture) {
auto* tex = create<sem::DepthTexture>(ast::TextureDimension::k2d); auto tex = ty.depth_texture(ast::TextureDimension::k2d);
auto result = table->Lookup(*this, IntrinsicType::kTextureLoad, auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
{tex, ty.vec2<i32>(), ty.i32()}, Source{}); {tex, ty.vec2<i32>(), ty.i32()}, Source{});
ASSERT_NE(result.intrinsic, nullptr); ASSERT_NE(result.intrinsic, nullptr);
@ -286,10 +286,9 @@ TEST_F(IntrinsicTableTest, MatchDepthTexture) {
} }
TEST_F(IntrinsicTableTest, MatchROStorageTexture) { TEST_F(IntrinsicTableTest, MatchROStorageTexture) {
auto* tex = create<sem::StorageTexture>( auto tex = ty.storage_texture(ast::TextureDimension::k2d,
ast::TextureDimension::k2d, ast::ImageFormat::kR16Float, ast::ImageFormat::kR16Float);
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR16Float, Types())); auto tex_ac = ty.access(ast::AccessControl::kReadOnly, tex);
auto* tex_ac = create<sem::AccessControl>(ast::AccessControl::kReadOnly, tex);
auto result = table->Lookup(*this, IntrinsicType::kTextureLoad, auto result = table->Lookup(*this, IntrinsicType::kTextureLoad,
{tex_ac, ty.vec2<i32>()}, Source{}); {tex_ac, ty.vec2<i32>()}, Source{});
ASSERT_NE(result.intrinsic, nullptr); ASSERT_NE(result.intrinsic, nullptr);
@ -303,11 +302,9 @@ TEST_F(IntrinsicTableTest, MatchROStorageTexture) {
} }
TEST_F(IntrinsicTableTest, MatchWOStorageTexture) { TEST_F(IntrinsicTableTest, MatchWOStorageTexture) {
auto* tex = create<sem::StorageTexture>( auto tex = ty.storage_texture(ast::TextureDimension::k2d,
ast::TextureDimension::k2d, ast::ImageFormat::kR16Float, ast::ImageFormat::kR16Float);
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR16Float, Types())); auto tex_ac = ty.access(ast::AccessControl::kWriteOnly, tex);
auto* tex_ac =
create<sem::AccessControl>(ast::AccessControl::kWriteOnly, tex);
auto result = auto result =
table->Lookup(*this, IntrinsicType::kTextureStore, table->Lookup(*this, IntrinsicType::kTextureStore,
{tex_ac, ty.vec2<i32>(), ty.vec4<f32>()}, Source{}); {tex_ac, ty.vec2<i32>(), ty.vec4<f32>()}, Source{});
@ -340,9 +337,9 @@ TEST_F(IntrinsicTableTest, MatchAutoPointerDereference) {
} }
TEST_F(IntrinsicTableTest, MatchWithAliasUnwrapping) { TEST_F(IntrinsicTableTest, MatchWithAliasUnwrapping) {
auto* alias_a = ty.alias("alias_a", ty.f32()); auto alias_a = ty.alias("alias_a", ty.f32());
auto* alias_b = ty.alias("alias_b", alias_a); auto alias_b = ty.alias("alias_b", alias_a);
auto* alias_c = ty.alias("alias_c", alias_b); auto alias_c = ty.alias("alias_c", alias_b);
auto result = table->Lookup(*this, IntrinsicType::kCos, {alias_c}, Source{}); auto result = table->Lookup(*this, IntrinsicType::kCos, {alias_c}, Source{});
ASSERT_NE(result.intrinsic, nullptr); ASSERT_NE(result.intrinsic, nullptr);
ASSERT_EQ(result.diagnostics.str(), ""); ASSERT_EQ(result.diagnostics.str(), "");
@ -352,12 +349,12 @@ TEST_F(IntrinsicTableTest, MatchWithAliasUnwrapping) {
} }
TEST_F(IntrinsicTableTest, MatchWithNestedAliasUnwrapping) { TEST_F(IntrinsicTableTest, MatchWithNestedAliasUnwrapping) {
auto* alias_a = ty.alias("alias_a", ty.bool_()); auto alias_a = ty.alias("alias_a", ty.bool_());
auto* alias_b = ty.alias("alias_b", alias_a); auto alias_b = ty.alias("alias_b", alias_a);
auto* alias_c = ty.alias("alias_c", alias_b); auto alias_c = ty.alias("alias_c", alias_b);
auto vec4_of_c = ty.vec4(alias_c); auto vec4_of_c = ty.vec4(alias_c);
auto* alias_d = ty.alias("alias_d", vec4_of_c); auto alias_d = ty.alias("alias_d", vec4_of_c);
auto* alias_e = ty.alias("alias_e", alias_d); auto alias_e = ty.alias("alias_e", alias_d);
auto result = table->Lookup(*this, IntrinsicType::kAll, {alias_e}, Source{}); auto result = table->Lookup(*this, IntrinsicType::kAll, {alias_e}, Source{});
ASSERT_NE(result.intrinsic, nullptr); ASSERT_NE(result.intrinsic, nullptr);
@ -464,7 +461,7 @@ TEST_F(IntrinsicTableTest, OverloadOrderByNumberOfParameters) {
} }
TEST_F(IntrinsicTableTest, OverloadOrderByMatchingParameter) { TEST_F(IntrinsicTableTest, OverloadOrderByMatchingParameter) {
auto* tex = create<sem::DepthTexture>(ast::TextureDimension::k2d); auto tex = ty.depth_texture(ast::TextureDimension::k2d);
auto result = table->Lookup(*this, IntrinsicType::kTextureDimensions, auto result = table->Lookup(*this, IntrinsicType::kTextureDimensions,
{tex, ty.bool_()}, Source{}); {tex, ty.bool_()}, Source{});
ASSERT_EQ( ASSERT_EQ(

View File

@ -18,6 +18,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include "src/ast/alias.h"
#include "src/ast/array.h" #include "src/ast/array.h"
#include "src/ast/array_accessor_expression.h" #include "src/ast/array_accessor_expression.h"
#include "src/ast/assignment_statement.h" #include "src/ast/assignment_statement.h"
@ -26,6 +27,7 @@
#include "src/ast/bool_literal.h" #include "src/ast/bool_literal.h"
#include "src/ast/call_expression.h" #include "src/ast/call_expression.h"
#include "src/ast/case_statement.h" #include "src/ast/case_statement.h"
#include "src/ast/depth_texture.h"
#include "src/ast/f32.h" #include "src/ast/f32.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "src/ast/i32.h" #include "src/ast/i32.h"
@ -34,10 +36,14 @@
#include "src/ast/matrix.h" #include "src/ast/matrix.h"
#include "src/ast/member_accessor_expression.h" #include "src/ast/member_accessor_expression.h"
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/ast/multisampled_texture.h"
#include "src/ast/pointer.h"
#include "src/ast/return_statement.h" #include "src/ast/return_statement.h"
#include "src/ast/sampled_texture.h"
#include "src/ast/scalar_constructor_expression.h" #include "src/ast/scalar_constructor_expression.h"
#include "src/ast/sint_literal.h" #include "src/ast/sint_literal.h"
#include "src/ast/stage_decoration.h" #include "src/ast/stage_decoration.h"
#include "src/ast/storage_texture.h"
#include "src/ast/stride_decoration.h" #include "src/ast/stride_decoration.h"
#include "src/ast/struct_member_align_decoration.h" #include "src/ast/struct_member_align_decoration.h"
#include "src/ast/struct_member_offset_decoration.h" #include "src/ast/struct_member_offset_decoration.h"
@ -55,10 +61,14 @@
#include "src/sem/alias_type.h" #include "src/sem/alias_type.h"
#include "src/sem/array_type.h" #include "src/sem/array_type.h"
#include "src/sem/bool_type.h" #include "src/sem/bool_type.h"
#include "src/sem/depth_texture_type.h"
#include "src/sem/f32_type.h" #include "src/sem/f32_type.h"
#include "src/sem/i32_type.h" #include "src/sem/i32_type.h"
#include "src/sem/matrix_type.h" #include "src/sem/matrix_type.h"
#include "src/sem/multisampled_texture_type.h"
#include "src/sem/pointer_type.h" #include "src/sem/pointer_type.h"
#include "src/sem/sampled_texture_type.h"
#include "src/sem/storage_texture_type.h"
#include "src/sem/struct_type.h" #include "src/sem/struct_type.h"
#include "src/sem/u32_type.h" #include "src/sem/u32_type.h"
#include "src/sem/vector_type.h" #include "src/sem/vector_type.h"
@ -363,24 +373,30 @@ class ProgramBuilder {
} }
/// @param type vector subtype /// @param type vector subtype
/// @return the tint AST type for a 2-element vector of `type`. /// @param n vector width in elements
typ::Vector vec2(typ::Type type) const { /// @return the tint AST type for a `n`-element vector of `type`.
return {builder->create<ast::Vector>(type, 2u), typ::Vector vec(typ::Type type, uint32_t n) const {
builder->create<sem::Vector>(type, 2u)}; return {builder->create<ast::Vector>(type, n),
builder->create<sem::Vector>(type, n)};
} }
/// @param type vector subtype
/// @return the tint AST type for a 2-element vector of `type`.
typ::Vector vec2(typ::Type type) const { return vec(type, 2u); }
/// @param type vector subtype /// @param type vector subtype
/// @return the tint AST type for a 3-element vector of `type`. /// @return the tint AST type for a 3-element vector of `type`.
typ::Vector vec3(typ::Type type) const { typ::Vector vec3(typ::Type type) const { return vec(type, 3u); }
return {builder->create<ast::Vector>(type, 3u),
builder->create<sem::Vector>(type, 3u)};
}
/// @param type vector subtype /// @param type vector subtype
/// @return the tint AST type for a 4-element vector of `type`. /// @return the tint AST type for a 4-element vector of `type`.
typ::Vector vec4(typ::Type type) const { typ::Vector vec4(typ::Type type) const { return vec(type, 4u); }
return {builder->create<ast::Vector>(type, 4u),
builder->create<sem::Vector>(type, 4u)}; /// @param n vector width in elements
/// @return the tint AST type for a `n`-element vector of `type`.
template <typename T>
typ::Vector vec(uint32_t n) const {
return vec(Of<T>(), n);
} }
/// @return the tint AST type for a 2-element vector of the C type `T`. /// @return the tint AST type for a 2-element vector of the C type `T`.
@ -401,6 +417,15 @@ class ProgramBuilder {
return vec4(Of<T>()); return vec4(Of<T>());
} }
/// @param type matrix subtype
/// @param columns number of columns for the matrix
/// @param rows number of rows for the matrix
/// @return the tint AST type for a matrix of `type`
typ::Matrix mat(typ::Type type, uint32_t columns, uint32_t rows) const {
return {builder->create<ast::Matrix>(type, rows, columns),
builder->create<sem::Matrix>(type, rows, columns)};
}
/// @param type matrix subtype /// @param type matrix subtype
/// @return the tint AST type for a 2x3 matrix of `type`. /// @return the tint AST type for a 2x3 matrix of `type`.
typ::Matrix mat2x2(typ::Type type) const { typ::Matrix mat2x2(typ::Type type) const {
@ -464,6 +489,14 @@ class ProgramBuilder {
builder->create<sem::Matrix>(type, 4u, 4u)}; builder->create<sem::Matrix>(type, 4u, 4u)};
} }
/// @param columns number of columns for the matrix
/// @param rows number of rows for the matrix
/// @return the tint AST type for a matrix of `type`
template <typename T>
typ::Matrix mat(uint32_t columns, uint32_t rows) const {
return mat(Of<T>(), columns, rows);
}
/// @return the tint AST type for a 2x3 matrix of the C type `T`. /// @return the tint AST type for a 2x3 matrix of the C type `T`.
template <typename T> template <typename T>
typ::Matrix mat2x2() const { typ::Matrix mat2x2() const {
@ -519,29 +552,23 @@ class ProgramBuilder {
} }
/// @param subtype the array element type /// @param subtype the array element type
/// @param n the array size. 0 represents a runtime-array. /// @param n the array size. 0 represents a runtime-array
/// @param decos the optional decorations for the array
/// @return the tint AST type for a array of size `n` of type `T` /// @return the tint AST type for a array of size `n` of type `T`
typ::Array array(typ::Type subtype, uint32_t n = 0) const { typ::Array array(typ::Type subtype,
return { uint32_t n = 0,
builder->create<ast::Array>(subtype, n, ast::DecorationList{}), ast::DecorationList decos = {}) const {
builder->create<sem::ArrayType>(subtype, n, ast::DecorationList{})}; return {builder->create<ast::Array>(subtype, n, decos),
builder->create<sem::ArrayType>(subtype, n, decos)};
} }
/// @param subtype the array element type /// @param subtype the array element type
/// @param n the array size. 0 represents a runtime-array. /// @param n the array size. 0 represents a runtime-array
/// @param stride the array stride. /// @param stride the array stride
/// @return the tint AST type for a array of size `n` of type `T` /// @return the tint AST type for a array of size `n` of type `T`
typ::Array array(typ::Type subtype, uint32_t n, uint32_t stride) const { typ::Array array(typ::Type subtype, uint32_t n, uint32_t stride) const {
return {builder->create<ast::Array>( return array(subtype, n,
subtype, n, {builder->create<ast::StrideDecoration>(stride)});
ast::DecorationList{
builder->create<ast::StrideDecoration>(stride),
}),
builder->create<sem::ArrayType>(
subtype, n,
ast::DecorationList{
builder->create<ast::StrideDecoration>(stride),
})};
} }
/// @return the tint AST type for an array of size `N` of type `T` /// @return the tint AST type for an array of size `N` of type `T`
@ -562,40 +589,88 @@ class ProgramBuilder {
/// @param type the alias type /// @param type the alias type
/// @returns the alias pointer /// @returns the alias pointer
template <typename NAME> template <typename NAME>
sem::Alias* alias(NAME&& name, sem::Type* type) const { typ::Alias alias(NAME&& name, typ::Type type) const {
return builder->create<sem::Alias>(builder->Sym(std::forward<NAME>(name)), auto sym = builder->Sym(std::forward<NAME>(name));
type); return {
builder->create<ast::Alias>(sym, type),
builder->create<sem::Alias>(sym, type),
};
} }
/// Creates an access control qualifier type /// Creates an access control qualifier type
/// @param access the access control /// @param access the access control
/// @param type the inner type /// @param type the inner type
/// @returns the access control qualifier type /// @returns the access control qualifier type
sem::AccessControl* access(ast::AccessControl::Access access, typ::AccessControl access(ast::AccessControl::Access access,
sem::Type* type) const { typ::Type type) const {
return builder->create<sem::AccessControl>(access, type); return {builder->create<ast::AccessControl>(access, type),
builder->create<sem::AccessControl>(access, type)};
} }
/// @return the tint AST pointer to `type` with the given ast::StorageClass
/// @param type the type of the pointer /// @param type the type of the pointer
/// @param storage_class the storage class of the pointer /// @param storage_class the storage class of the pointer
sem::Pointer* pointer(sem::Type* type, /// @return the pointer to `type` with the given ast::StorageClass
typ::Pointer pointer(typ::Type type,
ast::StorageClass storage_class) const { ast::StorageClass storage_class) const {
return builder->create<sem::Pointer>(type, storage_class); return {builder->create<ast::Pointer>(type, storage_class),
builder->create<sem::Pointer>(type, storage_class)};
} }
/// @return the tint AST pointer to type `T` with the given
/// ast::StorageClass.
/// @param storage_class the storage class of the pointer /// @param storage_class the storage class of the pointer
/// @return the pointer to type `T` with the given ast::StorageClass.
template <typename T> template <typename T>
sem::Pointer* pointer(ast::StorageClass storage_class) const { typ::Pointer pointer(ast::StorageClass storage_class) const {
return pointer(Of<T>(), storage_class); return pointer(Of<T>(), storage_class);
} }
/// @param impl the struct implementation /// @param impl the struct implementation
/// @returns a struct pointer /// @returns a struct pointer
sem::StructType* struct_(ast::Struct* impl) const { typ::Struct struct_(ast::Struct* impl) const {
return builder->create<sem::StructType>(impl); return {impl, builder->create<sem::StructType>(impl)};
}
/// @param kind the kind of sampler
/// @returns the sampler
typ::Sampler sampler(ast::SamplerKind kind) const {
return {builder->create<ast::Sampler>(kind),
builder->create<sem::Sampler>(kind)};
}
/// @param dims the dimensionality of the texture
/// @returns the depth texture
typ::DepthTexture depth_texture(ast::TextureDimension dims) const {
return {builder->create<ast::DepthTexture>(dims),
builder->create<sem::DepthTexture>(dims)};
}
/// @param dims the dimensionality of the texture
/// @param subtype the texture subtype.
/// @returns the sampled texture
typ::SampledTexture sampled_texture(ast::TextureDimension dims,
typ::Type subtype) const {
return {builder->create<ast::SampledTexture>(dims, subtype),
builder->create<sem::SampledTexture>(dims, subtype)};
}
/// @param dims the dimensionality of the texture
/// @param subtype the texture subtype.
/// @returns the multisampled texture
typ::MultisampledTexture multisampled_texture(ast::TextureDimension dims,
typ::Type subtype) const {
return {builder->create<ast::MultisampledTexture>(dims, subtype),
builder->create<sem::MultisampledTexture>(dims, subtype)};
}
/// @param dims the dimensionality of the texture
/// @param format the image format of the texture
/// @returns the storage texture
typ::StorageTexture storage_texture(ast::TextureDimension dims,
ast::ImageFormat format) const {
auto* ast_subtype = ast::StorageTexture::SubtypeFor(format, *builder);
auto* sem_subtype =
sem::StorageTexture::SubtypeFor(format, builder->Types());
return {builder->create<ast::StorageTexture>(dims, format, ast_subtype),
builder->create<sem::StorageTexture>(dims, format, sem_subtype)};
} }
private: private:
@ -904,7 +979,7 @@ class ProgramBuilder {
/// @return an `ast::TypeConstructorExpression` of an array with element type /// @return an `ast::TypeConstructorExpression` of an array with element type
/// `subtype`, constructed with the values `args`. /// `subtype`, constructed with the values `args`.
template <typename... ARGS> template <typename... ARGS>
ast::TypeConstructorExpression* array(sem::Type* subtype, ast::TypeConstructorExpression* array(typ::Type subtype,
uint32_t n, uint32_t n,
ARGS&&... args) { ARGS&&... args) {
return create<ast::TypeConstructorExpression>( return create<ast::TypeConstructorExpression>(
@ -1259,14 +1334,14 @@ class ProgramBuilder {
/// @param decorations the optional struct decorations /// @param decorations the optional struct decorations
/// @returns the struct type /// @returns the struct type
template <typename NAME> template <typename NAME>
sem::StructType* Structure(const Source& source, typ::Struct Structure(const Source& source,
NAME&& name, NAME&& name,
ast::StructMemberList members, ast::StructMemberList members,
ast::DecorationList decorations = {}) { ast::DecorationList decorations = {}) {
auto sym = Sym(std::forward<NAME>(name)); auto sym = Sym(std::forward<NAME>(name));
auto* impl = create<ast::Struct>(source, sym, std::move(members), auto* impl = create<ast::Struct>(source, sym, std::move(members),
std::move(decorations)); std::move(decorations));
auto* type = ty.struct_(impl); auto type = ty.struct_(impl);
AST().AddConstructedType(type); AST().AddConstructedType(type);
return type; return type;
} }
@ -1278,13 +1353,13 @@ class ProgramBuilder {
/// @param decorations the optional struct decorations /// @param decorations the optional struct decorations
/// @returns the struct type /// @returns the struct type
template <typename NAME> template <typename NAME>
sem::StructType* Structure(NAME&& name, typ::Struct Structure(NAME&& name,
ast::StructMemberList members, ast::StructMemberList members,
ast::DecorationList decorations = {}) { ast::DecorationList decorations = {}) {
auto sym = Sym(std::forward<NAME>(name)); auto sym = Sym(std::forward<NAME>(name));
auto* impl = auto* impl =
create<ast::Struct>(sym, std::move(members), std::move(decorations)); create<ast::Struct>(sym, std::move(members), std::move(decorations));
auto* type = ty.struct_(impl); auto type = ty.struct_(impl);
AST().AddConstructedType(type); AST().AddConstructedType(type);
return type; return type;
} }

View File

@ -1897,7 +1897,7 @@ sem::Pointer* ParserImpl::GetTypeForHandleVar(
// Construct the Tint handle type. // Construct the Tint handle type.
sem::Type* ast_store_type = nullptr; sem::Type* ast_store_type = nullptr;
if (usage.IsSampler()) { if (usage.IsSampler()) {
ast_store_type = builder_.create<sem::Sampler>( ast_store_type = builder_.ty.sampler(
usage.IsComparisonSampler() ? ast::SamplerKind::kComparisonSampler usage.IsComparisonSampler() ? ast::SamplerKind::kComparisonSampler
: ast::SamplerKind::kSampler); : ast::SamplerKind::kSampler);
} else if (usage.IsTexture()) { } else if (usage.IsTexture()) {

View File

@ -38,7 +38,7 @@ TEST_F(ParserImplTest, TypeDecl_ParsesType) {
TEST_F(ParserImplTest, TypeDecl_ParsesStruct_Ident) { TEST_F(ParserImplTest, TypeDecl_ParsesStruct_Ident) {
auto p = parser("type a = B"); auto p = parser("type a = B");
auto* str = Structure(p->builder().Symbols().Register("B"), {}); auto str = Structure(p->builder().Symbols().Register("B"), {});
p->register_constructed("B", str); p->register_constructed("B", str);
auto t = p->type_alias(); auto t = p->type_alias();

View File

@ -746,7 +746,7 @@ TEST_F(ParserImplTest, TypeDecl_Sampler) {
auto p = parser("sampler"); auto p = parser("sampler");
auto& builder = p->builder(); auto& builder = p->builder();
auto* type = builder.create<sem::Sampler>(ast::SamplerKind::kSampler); auto type = builder.ty.sampler(ast::SamplerKind::kSampler);
auto t = p->type_decl(); auto t = p->type_decl();
EXPECT_TRUE(t.matched); EXPECT_TRUE(t.matched);

View File

@ -115,7 +115,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_Read) {
ast::DecorationList decos; ast::DecorationList decos;
decos.push_back(block_deco); decos.push_back(block_deco);
auto* s = Structure(Sym("S"), members, decos); auto s = Structure(Sym("S"), members, decos);
p->register_constructed("S", s); p->register_constructed("S", s);
@ -139,7 +139,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_ParsesWithAccessDeco_ReadWrite) {
ast::DecorationList decos; ast::DecorationList decos;
decos.push_back(block_deco); decos.push_back(block_deco);
auto* s = Structure(Sym("S"), members, decos); auto s = Structure(Sym("S"), members, decos);
p->register_constructed("S", s); p->register_constructed("S", s);
@ -163,7 +163,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDecoFail) {
ast::DecorationList decos; ast::DecorationList decos;
decos.push_back(block_deco); decos.push_back(block_deco);
auto* s = Structure(Sym("S"), members, decos); auto s = Structure(Sym("S"), members, decos);
p->register_constructed("S", s); p->register_constructed("S", s);
@ -184,7 +184,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_MultipleAccessDeco_MultiBlock_Fail) {
ast::DecorationList decos; ast::DecorationList decos;
decos.push_back(block_deco); decos.push_back(block_deco);
auto* s = Structure(Sym("S"), members, decos); auto s = Structure(Sym("S"), members, decos);
p->register_constructed("S", s); p->register_constructed("S", s);
@ -221,7 +221,7 @@ TEST_F(ParserImplTest, VariableIdentDecl_NonAccessDecoFail) {
ast::DecorationList decos; ast::DecorationList decos;
decos.push_back(block_deco); decos.push_back(block_deco);
auto* s = Structure(Sym("S"), members, decos); auto s = Structure(Sym("S"), members, decos);
p->register_constructed("S", s); p->register_constructed("S", s);

View File

@ -166,7 +166,7 @@ TEST_F(ResolverAssignmentValidationTest,
// alias myint = i32; // alias myint = i32;
// var a :myint = 2; // var a :myint = 2;
// a = 2 // a = 2
auto* myint = ty.alias("myint", ty.i32()); auto myint = ty.alias("myint", ty.i32());
auto* var = Var("a", myint, ast::StorageClass::kNone, Expr(2)); auto* var = Var("a", myint, ast::StorageClass::kNone, Expr(2));
auto* lhs = Expr("a"); auto* lhs = Expr("a");
@ -237,11 +237,9 @@ TEST_F(ResolverAssignmentValidationTest, AssignFromPointer_Fail) {
// var b : [[access(read)]] texture_storage_1d<rgba8unorm>; // var b : [[access(read)]] texture_storage_1d<rgba8unorm>;
// a = b; // a = b;
auto* tex_type = create<sem::StorageTexture>( auto tex_type = ty.storage_texture(ast::TextureDimension::k1d,
ast::TextureDimension::k1d, ast::ImageFormat::kRgba8Unorm, ast::ImageFormat::kRgba8Unorm);
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kRgba8Unorm, Types())); auto tex_ac = ty.access(ast::AccessControl::kReadOnly, tex_type);
auto* tex_ac =
create<sem::AccessControl>(ast::AccessControl::kReadOnly, tex_type);
auto* var_a = Var("a", tex_ac, ast::StorageClass::kFunction); auto* var_a = Var("a", tex_ac, ast::StorageClass::kFunction);
auto* var_b = Var("b", tex_ac, ast::StorageClass::kFunction); auto* var_b = Var("b", tex_ac, ast::StorageClass::kFunction);

View File

@ -294,7 +294,7 @@ TEST_F(ResolverControlBlockValidationTest, SwitchCaseAlias_Pass) {
// default: {} // default: {}
// } // }
auto* my_int = ty.alias("MyInt", ty.u32()); auto my_int = ty.alias("MyInt", ty.u32());
auto* var = Var("a", my_int, ast::StorageClass::kNone, Expr(2u)); auto* var = Var("a", my_int, ast::StorageClass::kNone, Expr(2u));
ast::CaseSelectorList default_csl; ast::CaseSelectorList default_csl;

View File

@ -122,9 +122,9 @@ using ArrayDecorationTest = TestWithParams;
TEST_P(ArrayDecorationTest, IsValid) { TEST_P(ArrayDecorationTest, IsValid) {
auto& params = GetParam(); auto& params = GetParam();
auto* arr = create<sem::ArrayType>( auto arr =
ty.f32(), 0, ty.array(ty.f32(), 0,
ast::DecorationList{ {
createDecoration(Source{{12, 34}}, *this, params.kind), createDecoration(Source{{12, 34}}, *this, params.kind),
}); });
Structure("mystruct", Structure("mystruct",
@ -318,7 +318,7 @@ struct TestWithParams : ResolverTestWithParam<Params> {};
using ArrayStrideTest = TestWithParams; using ArrayStrideTest = TestWithParams;
TEST_P(ArrayStrideTest, All) { TEST_P(ArrayStrideTest, All) {
auto& params = GetParam(); auto& params = GetParam();
auto* el_ty = params.create_el_type(ty); auto el_ty = params.create_el_type(ty);
std::stringstream ss; std::stringstream ss;
ss << "el_ty: " << el_ty->FriendlyName(Symbols()) ss << "el_ty: " << el_ty->FriendlyName(Symbols())
@ -326,11 +326,7 @@ TEST_P(ArrayStrideTest, All) {
<< ", should_pass: " << params.should_pass; << ", should_pass: " << params.should_pass;
SCOPED_TRACE(ss.str()); SCOPED_TRACE(ss.str());
auto* arr = auto arr = ty.array(el_ty, 4, params.stride);
create<sem::ArrayType>(el_ty, 4,
ast::DecorationList{
create<ast::StrideDecoration>(params.stride),
});
Global(Source{{12, 34}}, "myarray", arr, ast::StorageClass::kInput); Global(Source{{12, 34}}, "myarray", arr, ast::StorageClass::kInput);
@ -415,8 +411,8 @@ INSTANTIATE_TEST_SUITE_P(
Params{ty_mat4x4<f32>, (default_mat4x4.align - 1) * 7, false})); Params{ty_mat4x4<f32>, (default_mat4x4.align - 1) * 7, false}));
TEST_F(ArrayStrideTest, MultipleDecorations) { TEST_F(ArrayStrideTest, MultipleDecorations) {
auto* arr = create<sem::ArrayType>(ty.i32(), 4, auto arr = ty.array(ty.i32(), 4,
ast::DecorationList{ {
create<ast::StrideDecoration>(4), create<ast::StrideDecoration>(4),
create<ast::StrideDecoration>(4), create<ast::StrideDecoration>(4),
}); });
@ -436,7 +432,7 @@ namespace {
using StructBlockTest = ResolverTest; using StructBlockTest = ResolverTest;
TEST_F(StructBlockTest, StructUsedAsArrayElement) { TEST_F(StructBlockTest, StructUsedAsArrayElement) {
auto* s = Structure("S", {Member("x", ty.i32())}, auto s = Structure("S", {Member("x", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto a = ty.array(s, 4); auto a = ty.array(s, 4);
Global("G", a, ast::StorageClass::kPrivate); Global("G", a, ast::StorageClass::kPrivate);

View File

@ -85,7 +85,7 @@ TEST_F(ResolverEntryPointValidationTest, ReturnTypeAttribute_Struct) {
// fn main() -> [[location(0)]] Output { // fn main() -> [[location(0)]] Output {
// return Output(); // return Output();
// } // }
auto* output = Structure("Output", {}); auto output = Structure("Output", {});
Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))},
{Stage(ast::PipelineStage::kVertex)}, {Location(Source{{13, 43}}, 0)}); {Stage(ast::PipelineStage::kVertex)}, {Location(Source{{13, 43}}, 0)});
@ -105,7 +105,7 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_Valid) {
// fn main() -> Output { // fn main() -> Output {
// return Output(); // return Output();
// } // }
auto* output = Structure( auto output = Structure(
"Output", {Member("a", ty.f32(), {Location(0)}), "Output", {Member("a", ty.f32(), {Location(0)}),
Member("b", ty.f32(), {Builtin(ast::Builtin::kFragDepth)})}); Member("b", ty.f32(), {Builtin(ast::Builtin::kFragDepth)})});
Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))},
@ -123,7 +123,7 @@ TEST_F(ResolverEntryPointValidationTest,
// fn main() -> Output { // fn main() -> Output {
// return Output(); // return Output();
// } // }
auto* output = Structure( auto output = Structure(
"Output", "Output",
{Member("a", ty.f32(), {Member("a", ty.f32(),
{Location(Source{{13, 43}}, 0), {Location(Source{{13, 43}}, 0),
@ -147,7 +147,7 @@ TEST_F(ResolverEntryPointValidationTest,
// fn main() -> Output { // fn main() -> Output {
// return Output(); // return Output();
// } // }
auto* output = Structure( auto output = Structure(
"Output", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}), "Output", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}),
Member(Source{{14, 52}}, "b", ty.f32(), {})}); Member(Source{{14, 52}}, "b", ty.f32(), {})});
Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))},
@ -170,9 +170,9 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_NestedStruct) {
// fn main() -> Output { // fn main() -> Output {
// return Output(); // return Output();
// } // }
auto* inner = Structure( auto inner = Structure(
"Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})}); "Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})});
auto* output = Structure( auto output = Structure(
"Output", {Member(Source{{14, 52}}, "a", inner, {Location(0)})}); "Output", {Member(Source{{14, 52}}, "a", inner, {Location(0)})});
Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))},
{Stage(ast::PipelineStage::kFragment)}); {Stage(ast::PipelineStage::kFragment)});
@ -193,7 +193,7 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_RuntimeArray) {
// fn main() -> Output { // fn main() -> Output {
// return Output(); // return Output();
// } // }
auto* output = Structure( auto output = Structure(
"Output", "Output",
{Member(Source{{13, 43}}, "a", ty.array<float>(), {Location(0)})}, {Member(Source{{13, 43}}, "a", ty.array<float>(), {Location(0)})},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
@ -216,7 +216,7 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_DuplicateBuiltins) {
// fn main() -> Output { // fn main() -> Output {
// return Output(); // return Output();
// } // }
auto* output = Structure( auto output = Structure(
"Output", {Member("a", ty.f32(), {Builtin(ast::Builtin::kFragDepth)}), "Output", {Member("a", ty.f32(), {Builtin(ast::Builtin::kFragDepth)}),
Member("b", ty.f32(), {Builtin(ast::Builtin::kFragDepth)})}); Member("b", ty.f32(), {Builtin(ast::Builtin::kFragDepth)})});
Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))},
@ -238,7 +238,7 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_DuplicateLocation) {
// fn main() -> Output { // fn main() -> Output {
// return Output(); // return Output();
// } // }
auto* output = Structure("Output", {Member("a", ty.f32(), {Location(1)}), auto output = Structure("Output", {Member("a", ty.f32(), {Location(1)}),
Member("b", ty.f32(), {Location(1)})}); Member("b", ty.f32(), {Location(1)})});
Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))}, Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))},
{Stage(ast::PipelineStage::kFragment)}); {Stage(ast::PipelineStage::kFragment)});
@ -302,7 +302,7 @@ TEST_F(ResolverEntryPointValidationTest, ParameterAttribute_Struct) {
// }; // };
// [[stage(fragment)]] // [[stage(fragment)]]
// fn main([[location(0)]] param : Input) {} // fn main([[location(0)]] param : Input) {}
auto* input = Structure("Input", {}); auto input = Structure("Input", {});
auto* param = Param("param", input, {Location(Source{{13, 43}}, 0)}); auto* param = Param("param", input, {Location(Source{{13, 43}}, 0)});
Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, Func(Source{{12, 34}}, "main", {param}, ty.void_(), {},
{Stage(ast::PipelineStage::kFragment)}); {Stage(ast::PipelineStage::kFragment)});
@ -321,7 +321,7 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_Valid) {
// }; // };
// [[stage(fragment)]] // [[stage(fragment)]]
// fn main(param : Input) {} // fn main(param : Input) {}
auto* input = Structure( auto input = Structure(
"Input", {Member("a", ty.f32(), {Location(0)}), "Input", {Member("a", ty.f32(), {Location(0)}),
Member("b", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)})}); Member("b", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)})});
auto* param = Param("param", input); auto* param = Param("param", input);
@ -338,7 +338,7 @@ TEST_F(ResolverEntryPointValidationTest,
// }; // };
// [[stage(fragment)]] // [[stage(fragment)]]
// fn main(param : Input) {} // fn main(param : Input) {}
auto* input = Structure( auto input = Structure(
"Input", "Input",
{Member("a", ty.f32(), {Member("a", ty.f32(),
{Location(Source{{13, 43}}, 0), {Location(Source{{13, 43}}, 0),
@ -361,7 +361,7 @@ TEST_F(ResolverEntryPointValidationTest,
// }; // };
// [[stage(fragment)]] // [[stage(fragment)]]
// fn main(param : Input) {} // fn main(param : Input) {}
auto* input = Structure( auto input = Structure(
"Input", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}), "Input", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)}),
Member(Source{{14, 52}}, "b", ty.f32(), {})}); Member(Source{{14, 52}}, "b", ty.f32(), {})});
auto* param = Param("param", input); auto* param = Param("param", input);
@ -382,9 +382,9 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_NestedStruct) {
// }; // };
// [[stage(fragment)]] // [[stage(fragment)]]
// fn main(param : Input) {} // fn main(param : Input) {}
auto* inner = Structure( auto inner = Structure(
"Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})}); "Inner", {Member(Source{{13, 43}}, "a", ty.f32(), {Location(0)})});
auto* input = auto input =
Structure("Input", {Member(Source{{14, 52}}, "a", inner, {Location(0)})}); Structure("Input", {Member(Source{{14, 52}}, "a", inner, {Location(0)})});
auto* param = Param("param", input); auto* param = Param("param", input);
Func(Source{{12, 34}}, "main", {param}, ty.void_(), {}, Func(Source{{12, 34}}, "main", {param}, ty.void_(), {},
@ -404,7 +404,7 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_RuntimeArray) {
// }; // };
// [[stage(fragment)]] // [[stage(fragment)]]
// fn main(param : Input) {} // fn main(param : Input) {}
auto* input = Structure( auto input = Structure(
"Input", "Input",
{Member(Source{{13, 43}}, "a", ty.array<float>(), {Location(0)})}, {Member(Source{{13, 43}}, "a", ty.array<float>(), {Location(0)})},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
@ -446,9 +446,9 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_DuplicateBuiltins) {
// }; // };
// [[stage(fragment)]] // [[stage(fragment)]]
// fn main(param_a : InputA, param_b : InputB) {} // fn main(param_a : InputA, param_b : InputB) {}
auto* input_a = Structure( auto input_a = Structure(
"InputA", {Member("a", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)})}); "InputA", {Member("a", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)})});
auto* input_b = Structure( auto input_b = Structure(
"InputB", {Member("a", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)})}); "InputB", {Member("a", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)})});
auto* param_a = Param("param_a", input_a); auto* param_a = Param("param_a", input_a);
auto* param_b = Param("param_b", input_b); auto* param_b = Param("param_b", input_b);
@ -486,8 +486,8 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_DuplicateLocation) {
// }; // };
// [[stage(fragment)]] // [[stage(fragment)]]
// fn main(param_a : InputA, param_b : InputB) {} // fn main(param_a : InputA, param_b : InputB) {}
auto* input_a = Structure("InputA", {Member("a", ty.f32(), {Location(1)})}); auto input_a = Structure("InputA", {Member("a", ty.f32(), {Location(1)})});
auto* input_b = Structure("InputB", {Member("a", ty.f32(), {Location(1)})}); auto input_b = Structure("InputB", {Member("a", ty.f32(), {Location(1)})});
auto* param_a = Param("param_a", input_a); auto* param_a = Param("param_a", input_a);
auto* param_b = Param("param_b", input_b); auto* param_b = Param("param_b", input_b);
Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {}, Func(Source{{12, 34}}, "main", {param_a, param_b}, ty.void_(), {},

View File

@ -157,7 +157,7 @@ TEST_F(ResolverFunctionValidationTest,
FunctionTypeMustMatchReturnStatementTypeF32Alias_pass) { FunctionTypeMustMatchReturnStatementTypeF32Alias_pass) {
// type myf32 = f32; // type myf32 = f32;
// fn func -> myf32 { return 2.0; } // fn func -> myf32 { return 2.0; }
auto* myf32 = ty.alias("myf32", ty.f32()); auto myf32 = ty.alias("myf32", ty.f32());
Func("func", ast::VariableList{}, myf32, Func("func", ast::VariableList{}, myf32,
ast::StatementList{ ast::StatementList{
Return(Source{Source::Location{12, 34}}, Expr(2.f)), Return(Source{Source::Location{12, 34}}, Expr(2.f)),
@ -171,7 +171,7 @@ TEST_F(ResolverFunctionValidationTest,
FunctionTypeMustMatchReturnStatementTypeF32Alias_fail) { FunctionTypeMustMatchReturnStatementTypeF32Alias_fail) {
// type myf32 = f32; // type myf32 = f32;
// fn func -> myf32 { return 2; } // fn func -> myf32 { return 2; }
auto* myf32 = ty.alias("myf32", ty.f32()); auto myf32 = ty.alias("myf32", ty.f32());
Func("func", ast::VariableList{}, myf32, Func("func", ast::VariableList{}, myf32,
ast::StatementList{ ast::StatementList{
Return(Source{Source::Location{12, 34}}, Expr(2u)), Return(Source{Source::Location{12, 34}}, Expr(2u)),

View File

@ -27,9 +27,9 @@ namespace {
using ResolverHostShareableValidationTest = ResolverTest; using ResolverHostShareableValidationTest = ResolverTest;
TEST_F(ResolverHostShareableValidationTest, BoolMember) { TEST_F(ResolverHostShareableValidationTest, BoolMember) {
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.bool_())}, auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.bool_())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kReadOnly, s); auto a = ty.access(ast::AccessControl::kReadOnly, s);
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -42,9 +42,9 @@ TEST_F(ResolverHostShareableValidationTest, BoolMember) {
} }
TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) { TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) {
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.vec3<bool>())}, auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.vec3<bool>())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kReadOnly, s); auto a = ty.access(ast::AccessControl::kReadOnly, s);
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -57,11 +57,11 @@ TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) {
} }
TEST_F(ResolverHostShareableValidationTest, Aliases) { TEST_F(ResolverHostShareableValidationTest, Aliases) {
auto* a1 = ty.alias("a1", ty.bool_()); auto a1 = ty.alias("a1", ty.bool_());
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", a1)}, auto s = Structure("S", {Member(Source{{12, 34}}, "x", a1)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
auto* a2 = ty.alias("a2", ac); auto a2 = ty.alias("a2", ac);
Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage); Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -74,13 +74,13 @@ TEST_F(ResolverHostShareableValidationTest, Aliases) {
} }
TEST_F(ResolverHostShareableValidationTest, NestedStructures) { TEST_F(ResolverHostShareableValidationTest, NestedStructures) {
auto* i1 = Structure("I1", {Member(Source{{1, 2}}, "x", ty.bool_())}); auto i1 = Structure("I1", {Member(Source{{1, 2}}, "x", ty.bool_())});
auto* i2 = Structure("I2", {Member(Source{{3, 4}}, "y", i1)}); auto i2 = Structure("I2", {Member(Source{{3, 4}}, "y", i1)});
auto* i3 = Structure("I3", {Member(Source{{5, 6}}, "z", i2)}); auto i3 = Structure("I3", {Member(Source{{5, 6}}, "z", i2)});
auto* s = Structure("S", {Member(Source{{7, 8}}, "m", i3)}, auto s = Structure("S", {Member(Source{{7, 8}}, "m", i3)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kReadOnly, s); auto a = ty.access(ast::AccessControl::kReadOnly, s);
Global(Source{{9, 10}}, "g", a, ast::StorageClass::kStorage); Global(Source{{9, 10}}, "g", a, ast::StorageClass::kStorage);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -96,27 +96,27 @@ TEST_F(ResolverHostShareableValidationTest, NestedStructures) {
} }
TEST_F(ResolverHostShareableValidationTest, NoError) { TEST_F(ResolverHostShareableValidationTest, NoError) {
auto* i1 = auto i1 =
Structure("I1", { Structure("I1", {
Member(Source{{1, 1}}, "x1", ty.f32()), Member(Source{{1, 1}}, "x1", ty.f32()),
Member(Source{{2, 1}}, "y1", ty.vec3<f32>()), Member(Source{{2, 1}}, "y1", ty.vec3<f32>()),
Member(Source{{3, 1}}, "z1", ty.array<i32, 4>()), Member(Source{{3, 1}}, "z1", ty.array<i32, 4>()),
}); });
auto* i2 = Structure("I2", { auto i2 = Structure("I2", {
Member(Source{{4, 1}}, "x2", ty.mat2x2<f32>()), Member(Source{{4, 1}}, "x2", ty.mat2x2<f32>()),
Member(Source{{5, 1}}, "y2", i1), Member(Source{{5, 1}}, "y2", i1),
Member(Source{{6, 1}}, "z2", ty.mat3x2<i32>()), Member(Source{{6, 1}}, "z2", ty.mat3x2<i32>()),
}); });
auto* i3 = auto i3 =
Structure("I3", { Structure("I3", {
Member(Source{{4, 1}}, "x3", ty.alias("a1", i1)), Member(Source{{4, 1}}, "x3", ty.alias("a1", i1)),
Member(Source{{5, 1}}, "y3", i2), Member(Source{{5, 1}}, "y3", i2),
Member(Source{{6, 1}}, "z3", ty.alias("a2", i2)), Member(Source{{6, 1}}, "z3", ty.alias("a2", i2)),
}); });
auto* s = Structure("S", {Member(Source{{7, 8}}, "m", i3)}, auto s = Structure("S", {Member(Source{{7, 8}}, "m", i3)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kReadOnly, s); auto a = ty.access(ast::AccessControl::kReadOnly, s);
Global(Source{{9, 10}}, "g", a, ast::StorageClass::kStorage); Global(Source{{9, 10}}, "g", a, ast::StorageClass::kStorage);
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();

View File

@ -223,17 +223,17 @@ class ResolverIntrinsicTest_TextureOperation
/// @param dim dimensionality of the texture being sampled /// @param dim dimensionality of the texture being sampled
/// @param scalar the scalar type /// @param scalar the scalar type
/// @returns a pointer to a type appropriate for the coord param /// @returns a pointer to a type appropriate for the coord param
sem::Type* GetCoordsType(ast::TextureDimension dim, sem::Type* scalar) { typ::Type GetCoordsType(ast::TextureDimension dim, typ::Type scalar) {
switch (dim) { switch (dim) {
case ast::TextureDimension::k1d: case ast::TextureDimension::k1d:
return scalar; return scalar;
case ast::TextureDimension::k2d: case ast::TextureDimension::k2d:
case ast::TextureDimension::k2dArray: case ast::TextureDimension::k2dArray:
return create<sem::Vector>(scalar, 2); return ty.vec(scalar, 2);
case ast::TextureDimension::k3d: case ast::TextureDimension::k3d:
case ast::TextureDimension::kCube: case ast::TextureDimension::kCube:
case ast::TextureDimension::kCubeArray: case ast::TextureDimension::kCubeArray:
return create<sem::Vector>(scalar, 3); return ty.vec(scalar, 3);
default: default:
[=]() { FAIL() << "Unsupported texture dimension: " << dim; }(); [=]() { FAIL() << "Unsupported texture dimension: " << dim; }();
} }
@ -241,19 +241,19 @@ class ResolverIntrinsicTest_TextureOperation
} }
void add_call_param(std::string name, void add_call_param(std::string name,
sem::Type* type, typ::Type type,
ast::ExpressionList* call_params) { ast::ExpressionList* call_params) {
Global(name, type, ast::StorageClass::kInput); Global(name, type, ast::StorageClass::kInput);
call_params->push_back(Expr(name)); call_params->push_back(Expr(name));
} }
sem::Type* subtype(Texture type) { typ::Type subtype(Texture type) {
if (type == Texture::kF32) { if (type == Texture::kF32) {
return create<sem::F32>(); return ty.f32();
} }
if (type == Texture::kI32) { if (type == Texture::kI32) {
return create<sem::I32>(); return ty.i32();
} }
return create<sem::U32>(); return ty.u32();
} }
}; };
@ -264,12 +264,9 @@ TEST_P(ResolverIntrinsicTest_StorageTextureOperation, TextureLoadRo) {
auto type = GetParam().type; auto type = GetParam().type;
auto format = GetParam().format; auto format = GetParam().format;
auto* coords_type = GetCoordsType(dim, ty.i32()); auto coords_type = GetCoordsType(dim, ty.i32());
auto texture_type = ty.storage_texture(dim, format);
auto* subtype = sem::StorageTexture::SubtypeFor(format, Types()); auto ro_texture_type = ty.access(ast::AccessControl::kReadOnly, texture_type);
auto* texture_type = create<sem::StorageTexture>(dim, format, subtype);
auto* ro_texture_type =
create<sem::AccessControl>(ast::AccessControl::kReadOnly, texture_type);
ast::ExpressionList call_params; ast::ExpressionList call_params;
@ -332,9 +329,9 @@ TEST_P(ResolverIntrinsicTest_SampledTextureOperation, TextureLoadSampled) {
auto dim = GetParam().dim; auto dim = GetParam().dim;
auto type = GetParam().type; auto type = GetParam().type;
sem::Type* s = subtype(type); auto s = subtype(type);
auto* coords_type = GetCoordsType(dim, ty.i32()); auto coords_type = GetCoordsType(dim, ty.i32());
auto* texture_type = create<sem::SampledTexture>(dim, s); auto texture_type = ty.sampled_texture(dim, s);
ast::ExpressionList call_params; ast::ExpressionList call_params;
@ -760,9 +757,9 @@ using ResolverIntrinsicDataTest = ResolverTest;
TEST_F(ResolverIntrinsicDataTest, ArrayLength_Vector) { TEST_F(ResolverIntrinsicDataTest, ArrayLength_Vector) {
auto ary = ty.array<i32>(); auto ary = ty.array<i32>();
auto* str = Structure("S", {Member("x", ary)}, auto str = Structure("S", {Member("x", ary)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kReadOnly, str); auto ac = ty.access(ast::AccessControl::kReadOnly, str);
Global("a", ac, ast::StorageClass::kStorage); Global("a", ac, ast::StorageClass::kStorage);
auto* call = Call("arrayLength", MemberAccessor("a", "x")); auto* call = Call("arrayLength", MemberAccessor("a", "x"));
@ -1950,7 +1947,7 @@ TEST_P(ResolverIntrinsicTest_Texture, Call) {
case ast::intrinsic::test::TextureKind::kRegular: case ast::intrinsic::test::TextureKind::kRegular:
case ast::intrinsic::test::TextureKind::kMultisampled: case ast::intrinsic::test::TextureKind::kMultisampled:
case ast::intrinsic::test::TextureKind::kStorage: { case ast::intrinsic::test::TextureKind::kStorage: {
auto* datatype = param.resultVectorComponentType(this); auto datatype = param.resultVectorComponentType(this);
ASSERT_TRUE(TypeOf(call)->Is<sem::Vector>()); ASSERT_TRUE(TypeOf(call)->Is<sem::Vector>());
EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->type(), datatype); EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->type(), datatype);
break; break;

View File

@ -89,12 +89,12 @@ TEST_F(ResolverIsHostShareable, AliasI32) {
TEST_F(ResolverIsHostShareable, AccessControlVoid) { TEST_F(ResolverIsHostShareable, AccessControlVoid) {
EXPECT_FALSE(r()->IsHostShareable( EXPECT_FALSE(r()->IsHostShareable(
create<sem::AccessControl>(ast::AccessControl::kReadOnly, ty.void_()))); ty.access(ast::AccessControl::kReadOnly, ty.void_())));
} }
TEST_F(ResolverIsHostShareable, AccessControlI32) { TEST_F(ResolverIsHostShareable, AccessControlI32) {
EXPECT_TRUE(r()->IsHostShareable( EXPECT_TRUE(
create<sem::AccessControl>(ast::AccessControl::kReadOnly, ty.i32()))); r()->IsHostShareable(ty.access(ast::AccessControl::kReadOnly, ty.i32())));
} }
TEST_F(ResolverIsHostShareable, ArraySizedOfHostShareable) { TEST_F(ResolverIsHostShareable, ArraySizedOfHostShareable) {
@ -113,7 +113,7 @@ TEST_F(ResolverIsHostShareable, Struct_AllMembersHostShareable) {
} }
TEST_F(ResolverIsHostShareable, Struct_SomeMembersNonHostShareable) { TEST_F(ResolverIsHostShareable, Struct_SomeMembersNonHostShareable) {
auto* ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate); auto ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->IsHostShareable(Structure("S", { EXPECT_FALSE(r()->IsHostShareable(Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ptr_ty), Member("b", ptr_ty),
@ -121,7 +121,7 @@ TEST_F(ResolverIsHostShareable, Struct_SomeMembersNonHostShareable) {
} }
TEST_F(ResolverIsHostShareable, Struct_NestedHostShareable) { TEST_F(ResolverIsHostShareable, Struct_NestedHostShareable) {
auto* host_shareable = Structure("S", { auto host_shareable = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
@ -133,8 +133,8 @@ TEST_F(ResolverIsHostShareable, Struct_NestedHostShareable) {
} }
TEST_F(ResolverIsHostShareable, Struct_NestedNonHostShareable) { TEST_F(ResolverIsHostShareable, Struct_NestedNonHostShareable) {
auto* ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate); auto ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate);
auto* non_host_shareable = auto non_host_shareable =
Structure("non_host_shareable", { Structure("non_host_shareable", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ptr_ty), Member("b", ptr_ty),

View File

@ -97,7 +97,7 @@ TEST_F(ResolverIsStorableTest, Struct_AllMembersStorable) {
} }
TEST_F(ResolverIsStorableTest, Struct_SomeMembersNonStorable) { TEST_F(ResolverIsStorableTest, Struct_SomeMembersNonStorable) {
auto* ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate); auto ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate);
EXPECT_FALSE(r()->IsStorable(Structure("S", { EXPECT_FALSE(r()->IsStorable(Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ptr_ty), Member("b", ptr_ty),
@ -105,7 +105,7 @@ TEST_F(ResolverIsStorableTest, Struct_SomeMembersNonStorable) {
} }
TEST_F(ResolverIsStorableTest, Struct_NestedStorable) { TEST_F(ResolverIsStorableTest, Struct_NestedStorable) {
auto* storable = Structure("S", { auto storable = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
@ -116,8 +116,8 @@ TEST_F(ResolverIsStorableTest, Struct_NestedStorable) {
} }
TEST_F(ResolverIsStorableTest, Struct_NestedNonStorable) { TEST_F(ResolverIsStorableTest, Struct_NestedNonStorable) {
auto* ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate); auto ptr_ty = ty.pointer<i32>(ast::StorageClass::kPrivate);
auto* non_storable = Structure("nonstorable", { auto non_storable = Structure("nonstorable", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ptr_ty), Member("b", ptr_ty),
}); });

View File

@ -260,7 +260,7 @@ TEST_F(ResolverTest, Stmt_VariableDecl) {
} }
TEST_F(ResolverTest, Stmt_VariableDecl_Alias) { TEST_F(ResolverTest, Stmt_VariableDecl_Alias) {
auto* my_int = ty.alias("MyInt", ty.i32()); auto my_int = ty.alias("MyInt", ty.i32());
auto* var = Var("my_var", my_int, ast::StorageClass::kNone, Expr(2)); auto* var = Var("my_var", my_int, ast::StorageClass::kNone, Expr(2));
auto* init = var->constructor(); auto* init = var->constructor();
@ -407,7 +407,7 @@ TEST_F(ResolverTest, Expr_ArrayAccessor_Array) {
} }
TEST_F(ResolverTest, Expr_ArrayAccessor_Alias_Array) { TEST_F(ResolverTest, Expr_ArrayAccessor_Alias_Array) {
auto* aary = ty.alias("myarrty", ty.array<f32, 3>()); auto aary = ty.alias("myarrty", ty.array<f32, 3>());
Global("my_var", aary, ast::StorageClass::kFunction); Global("my_var", aary, ast::StorageClass::kFunction);
@ -761,9 +761,9 @@ TEST_F(ResolverTest, Function_Parameters) {
} }
TEST_F(ResolverTest, Function_RegisterInputOutputVariables) { TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
auto* s = Structure("S", {Member("m", ty.u32())}, auto s = Structure("S", {Member("m", ty.u32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kReadOnly, s); auto a = ty.access(ast::AccessControl::kReadOnly, s);
auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput); auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput);
auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput); auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput);
@ -796,9 +796,9 @@ TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
} }
TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) { TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
auto* s = Structure("S", {Member("m", ty.u32())}, auto s = Structure("S", {Member("m", ty.u32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kReadOnly, s); auto a = ty.access(ast::AccessControl::kReadOnly, s);
auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput); auto* in_var = Global("in_var", ty.f32(), ast::StorageClass::kInput);
auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput); auto* out_var = Global("out_var", ty.f32(), ast::StorageClass::kOutput);
@ -878,7 +878,7 @@ TEST_F(ResolverTest, Function_ReturnStatements) {
} }
TEST_F(ResolverTest, Expr_MemberAccessor_Struct) { TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
auto* st = Structure("S", {Member("first_member", ty.i32()), auto st = Structure("S", {Member("first_member", ty.i32()),
Member("second_member", ty.f32())}); Member("second_member", ty.f32())});
Global("my_struct", st, ast::StorageClass::kInput); Global("my_struct", st, ast::StorageClass::kInput);
@ -903,9 +903,9 @@ TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
} }
TEST_F(ResolverTest, Expr_MemberAccessor_Struct_Alias) { TEST_F(ResolverTest, Expr_MemberAccessor_Struct_Alias) {
auto* st = Structure("alias", {Member("first_member", ty.i32()), auto st = Structure("alias", {Member("first_member", ty.i32()),
Member("second_member", ty.f32())}); Member("second_member", ty.f32())});
auto* alias = ty.alias("alias", st); auto alias = ty.alias("alias", st);
Global("my_struct", alias, ast::StorageClass::kInput); Global("my_struct", alias, ast::StorageClass::kInput);
auto* mem = MemberAccessor("my_struct", "second_member"); auto* mem = MemberAccessor("my_struct", "second_member");
@ -981,11 +981,11 @@ TEST_F(ResolverTest, Expr_Accessor_MultiLevel) {
// } // }
// //
auto* stB = Structure("B", {Member("foo", ty.vec4<f32>())}); auto stB = Structure("B", {Member("foo", ty.vec4<f32>())});
sem::Vector vecB(stB, 3); sem::Vector vecB(stB, 3);
auto* stA = Structure("A", {Member("mem", &vecB)}); auto stA = Structure("A", {Member("mem", &vecB)});
Global("c", stA, ast::StorageClass::kInput); Global("c", stA, ast::StorageClass::kInput);
auto* mem = MemberAccessor( auto* mem = MemberAccessor(
@ -1003,7 +1003,7 @@ TEST_F(ResolverTest, Expr_Accessor_MultiLevel) {
} }
TEST_F(ResolverTest, Expr_MemberAccessor_InBinaryOp) { TEST_F(ResolverTest, Expr_MemberAccessor_InBinaryOp) {
auto* st = Structure("S", {Member("first_member", ty.f32()), auto st = Structure("S", {Member("first_member", ty.f32()),
Member("second_member", ty.f32())}); Member("second_member", ty.f32())});
Global("my_struct", st, ast::StorageClass::kInput); Global("my_struct", st, ast::StorageClass::kInput);
@ -1181,9 +1181,9 @@ using Expr_Binary_Test_Valid = ResolverTestWithParam<Params>;
TEST_P(Expr_Binary_Test_Valid, All) { TEST_P(Expr_Binary_Test_Valid, All) {
auto& params = GetParam(); auto& params = GetParam();
auto* lhs_type = params.create_lhs_type(ty); auto lhs_type = params.create_lhs_type(ty);
auto* rhs_type = params.create_rhs_type(ty); auto rhs_type = params.create_rhs_type(ty);
auto* result_type = params.create_result_type(ty); auto result_type = params.create_result_type(ty);
std::stringstream ss; std::stringstream ss;
ss << lhs_type->FriendlyName(Symbols()) << " " << params.op << " " ss << lhs_type->FriendlyName(Symbols()) << " " << params.op << " "
@ -1212,8 +1212,8 @@ TEST_P(Expr_Binary_Test_WithAlias_Valid, All) {
const Params& params = std::get<0>(GetParam()); const Params& params = std::get<0>(GetParam());
BinaryExprSide side = std::get<1>(GetParam()); BinaryExprSide side = std::get<1>(GetParam());
auto* lhs_type = params.create_lhs_type(ty); auto lhs_type = params.create_lhs_type(ty);
auto* rhs_type = params.create_rhs_type(ty); auto rhs_type = params.create_rhs_type(ty);
std::stringstream ss; std::stringstream ss;
ss << lhs_type->FriendlyName(Symbols()) << " " << params.op << " " ss << lhs_type->FriendlyName(Symbols()) << " " << params.op << " "
@ -1287,8 +1287,8 @@ TEST_P(Expr_Binary_Test_Invalid, All) {
return; return;
} }
auto* lhs_type = params.create_lhs_type(ty); auto lhs_type = params.create_lhs_type(ty);
auto* rhs_type = create_type_func(ty); auto rhs_type = create_type_func(ty);
// Skip exceptions: multiplication of f32, vecN<f32>, and matNxN<f32> // Skip exceptions: multiplication of f32, vecN<f32>, and matNxN<f32>
if (params.op == Op::kMultiply && if (params.op == Op::kMultiply &&
@ -1331,20 +1331,20 @@ TEST_P(Expr_Binary_Test_Invalid_VectorMatrixMultiply, All) {
uint32_t mat_rows = std::get<2>(GetParam()); uint32_t mat_rows = std::get<2>(GetParam());
uint32_t mat_cols = std::get<3>(GetParam()); uint32_t mat_cols = std::get<3>(GetParam());
sem::Type* lhs_type; typ::Type lhs_type;
sem::Type* rhs_type; typ::Type rhs_type;
sem::Type* result_type; typ::Type result_type;
bool is_valid_expr; bool is_valid_expr;
if (vec_by_mat) { if (vec_by_mat) {
lhs_type = create<sem::Vector>(ty.f32(), vec_size); lhs_type = ty.vec<f32>(vec_size);
rhs_type = create<sem::Matrix>(ty.f32(), mat_rows, mat_cols); rhs_type = ty.mat<f32>(mat_cols, mat_rows);
result_type = create<sem::Vector>(ty.f32(), mat_cols); result_type = ty.vec<f32>(mat_cols);
is_valid_expr = vec_size == mat_rows; is_valid_expr = vec_size == mat_rows;
} else { } else {
lhs_type = create<sem::Matrix>(ty.f32(), mat_rows, mat_cols); lhs_type = ty.mat<f32>(mat_cols, mat_rows);
rhs_type = create<sem::Vector>(ty.f32(), vec_size); rhs_type = ty.vec<f32>(vec_size);
result_type = create<sem::Vector>(ty.f32(), mat_rows); result_type = ty.vec<f32>(mat_rows);
is_valid_expr = vec_size == mat_cols; is_valid_expr = vec_size == mat_cols;
} }
@ -1383,9 +1383,9 @@ TEST_P(Expr_Binary_Test_Invalid_MatrixMatrixMultiply, All) {
uint32_t rhs_mat_rows = std::get<2>(GetParam()); uint32_t rhs_mat_rows = std::get<2>(GetParam());
uint32_t rhs_mat_cols = std::get<3>(GetParam()); uint32_t rhs_mat_cols = std::get<3>(GetParam());
auto* lhs_type = create<sem::Matrix>(ty.f32(), lhs_mat_rows, lhs_mat_cols); auto lhs_type = ty.mat<f32>(lhs_mat_cols, lhs_mat_rows);
auto* rhs_type = create<sem::Matrix>(ty.f32(), rhs_mat_rows, rhs_mat_cols); auto rhs_type = ty.mat<f32>(rhs_mat_cols, rhs_mat_rows);
auto* result_type = create<sem::Matrix>(ty.f32(), lhs_mat_rows, rhs_mat_cols); auto result_type = ty.mat<f32>(rhs_mat_cols, lhs_mat_rows);
Global("lhs", lhs_type, ast::StorageClass::kInput); Global("lhs", lhs_type, ast::StorageClass::kInput);
Global("rhs", rhs_type, ast::StorageClass::kInput); Global("rhs", rhs_type, ast::StorageClass::kInput);

View File

@ -105,97 +105,91 @@ template <typename T>
class ResolverTestWithParam : public TestHelper, class ResolverTestWithParam : public TestHelper,
public testing::TestWithParam<T> {}; public testing::TestWithParam<T> {};
inline sem::Type* ty_bool_(const ProgramBuilder::TypesBuilder& ty) { inline typ::Type ty_bool_(const ProgramBuilder::TypesBuilder& ty) {
return ty.bool_(); return ty.bool_();
} }
inline sem::Type* ty_i32(const ProgramBuilder::TypesBuilder& ty) { inline typ::Type ty_i32(const ProgramBuilder::TypesBuilder& ty) {
return ty.i32(); return ty.i32();
} }
inline sem::Type* ty_u32(const ProgramBuilder::TypesBuilder& ty) { inline typ::Type ty_u32(const ProgramBuilder::TypesBuilder& ty) {
return ty.u32(); return ty.u32();
} }
inline sem::Type* ty_f32(const ProgramBuilder::TypesBuilder& ty) { inline typ::Type ty_f32(const ProgramBuilder::TypesBuilder& ty) {
return ty.f32(); return ty.f32();
} }
using create_type_func_ptr = using create_type_func_ptr =
sem::Type* (*)(const ProgramBuilder::TypesBuilder& ty); typ::Type (*)(const ProgramBuilder::TypesBuilder& ty);
template <typename T> template <typename T>
sem::Type* ty_vec2(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_vec2(const ProgramBuilder::TypesBuilder& ty) {
return ty.vec2<T>(); return ty.vec2<T>();
} }
template <create_type_func_ptr create_type> template <create_type_func_ptr create_type>
sem::Type* ty_vec2(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_vec2(const ProgramBuilder::TypesBuilder& ty) {
auto* type = create_type(ty); return ty.vec2(create_type(ty));
return ty.vec2(type);
} }
template <typename T> template <typename T>
sem::Type* ty_vec3(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_vec3(const ProgramBuilder::TypesBuilder& ty) {
return ty.vec3<T>(); return ty.vec3<T>();
} }
template <create_type_func_ptr create_type> template <create_type_func_ptr create_type>
sem::Type* ty_vec3(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_vec3(const ProgramBuilder::TypesBuilder& ty) {
auto* type = create_type(ty); return ty.vec3(create_type(ty));
return ty.vec3(type);
} }
template <typename T> template <typename T>
sem::Type* ty_vec4(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_vec4(const ProgramBuilder::TypesBuilder& ty) {
return ty.vec4<T>(); return ty.vec4<T>();
} }
template <create_type_func_ptr create_type> template <create_type_func_ptr create_type>
sem::Type* ty_vec4(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_vec4(const ProgramBuilder::TypesBuilder& ty) {
auto* type = create_type(ty); return ty.vec4(create_type(ty));
return ty.vec4(type);
} }
template <typename T> template <typename T>
sem::Type* ty_mat2x2(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_mat2x2(const ProgramBuilder::TypesBuilder& ty) {
return ty.mat2x2<T>(); return ty.mat2x2<T>();
} }
template <create_type_func_ptr create_type> template <create_type_func_ptr create_type>
sem::Type* ty_mat2x2(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_mat2x2(const ProgramBuilder::TypesBuilder& ty) {
auto* type = create_type(ty); return ty.mat2x2(create_type(ty));
return ty.mat2x2(type);
} }
template <typename T> template <typename T>
sem::Type* ty_mat3x3(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_mat3x3(const ProgramBuilder::TypesBuilder& ty) {
return ty.mat3x3<T>(); return ty.mat3x3<T>();
} }
template <create_type_func_ptr create_type> template <create_type_func_ptr create_type>
sem::Type* ty_mat3x3(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_mat3x3(const ProgramBuilder::TypesBuilder& ty) {
auto* type = create_type(ty); return ty.mat3x3(create_type(ty));
return ty.mat3x3(type);
} }
template <typename T> template <typename T>
sem::Type* ty_mat4x4(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_mat4x4(const ProgramBuilder::TypesBuilder& ty) {
return ty.mat4x4<T>(); return ty.mat4x4<T>();
} }
template <create_type_func_ptr create_type> template <create_type_func_ptr create_type>
sem::Type* ty_mat4x4(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_mat4x4(const ProgramBuilder::TypesBuilder& ty) {
auto* type = create_type(ty); return ty.mat4x4(create_type(ty));
return ty.mat4x4(type);
} }
template <create_type_func_ptr create_type> template <create_type_func_ptr create_type>
sem::Type* ty_alias(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_alias(const ProgramBuilder::TypesBuilder& ty) {
auto* type = create_type(ty); auto type = create_type(ty);
return ty.alias("alias_" + type->type_name(), type); return ty.alias("alias_" + type->type_name(), type);
} }
template <create_type_func_ptr create_type> template <create_type_func_ptr create_type>
sem::Type* ty_access(const ProgramBuilder::TypesBuilder& ty) { typ::Type ty_access(const ProgramBuilder::TypesBuilder& ty) {
auto* type = create_type(ty); auto type = create_type(ty);
return ty.access(ast::AccessControl::kReadOnly, type); return ty.access(ast::AccessControl::kReadOnly, type);
} }

View File

@ -60,9 +60,9 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) {
TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) { TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) {
// var<storage> g : [[access(read)]] array<S, 3>; // var<storage> g : [[access(read)]] array<S, 3>;
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
auto a = ty.array(s, 3); auto a = ty.array(s, 3);
auto* ac = ty.access(ast::AccessControl::kReadOnly, a); auto ac = ty.access(ast::AccessControl::kReadOnly, a);
Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kStorage); Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kStorage);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -75,7 +75,7 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferArray) {
TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) { TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) {
// type a = bool; // type a = bool;
// var<storage> g : [[access(read)]] a; // var<storage> g : [[access(read)]] a;
auto* a = ty.alias("a", ty.bool_()); auto a = ty.alias("a", ty.bool_());
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -87,7 +87,7 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) {
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoAccessControl) { TEST_F(ResolverStorageClassValidationTest, StorageBufferNoAccessControl) {
// var<storage> g : S; // var<storage> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}); auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())});
Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage); Global(Source{{56, 78}}, "g", s, ast::StorageClass::kStorage);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -100,8 +100,8 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferNoAccessControl) {
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoBlockDecoration) { TEST_F(ResolverStorageClassValidationTest, StorageBufferNoBlockDecoration) {
// struct S { x : i32 }; // struct S { x : i32 };
// var<storage> g : [[access(read)]] S; // var<storage> g : [[access(read)]] S;
auto* s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())}); auto s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())});
auto* a = ty.access(ast::AccessControl::kReadOnly, s); auto a = ty.access(ast::AccessControl::kReadOnly, s);
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -115,9 +115,9 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferNoBlockDecoration) {
TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Basic) { TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Basic) {
// [[block]] struct S { x : i32 }; // [[block]] struct S { x : i32 };
// var<storage> g : [[access(read)]] S; // var<storage> g : [[access(read)]] S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kReadOnly, s); auto a = ty.access(ast::AccessControl::kReadOnly, s);
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage);
ASSERT_TRUE(r()->Resolve()); ASSERT_TRUE(r()->Resolve());
@ -128,11 +128,11 @@ TEST_F(ResolverStorageClassValidationTest, StorageBufferNoError_Aliases) {
// type a1 = S; // type a1 = S;
// type a2 = [[access(read)]] a1; // type a2 = [[access(read)]] a1;
// var<storage> g : a2; // var<storage> g : a2;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a1 = ty.alias("a1", s); auto a1 = ty.alias("a1", s);
auto* ac = ty.access(ast::AccessControl::kReadOnly, a1); auto ac = ty.access(ast::AccessControl::kReadOnly, a1);
auto* a2 = ty.alias("a2", ac); auto a2 = ty.alias("a2", ac);
Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage); Global(Source{{56, 78}}, "g", a2, ast::StorageClass::kStorage);
ASSERT_TRUE(r()->Resolve()); ASSERT_TRUE(r()->Resolve());
@ -165,9 +165,9 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferPointer) {
TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) { TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) {
// var<uniform> g : [[access(read)]] array<S, 3>; // var<uniform> g : [[access(read)]] array<S, 3>;
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
auto a = ty.array(s, 3); auto a = ty.array(s, 3);
auto* ac = ty.access(ast::AccessControl::kReadOnly, a); auto ac = ty.access(ast::AccessControl::kReadOnly, a);
Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kUniform); Global(Source{{56, 78}}, "g", ac, ast::StorageClass::kUniform);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -180,7 +180,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferArray) {
TEST_F(ResolverStorageClassValidationTest, UniformBufferBoolAlias) { TEST_F(ResolverStorageClassValidationTest, UniformBufferBoolAlias) {
// type a = bool; // type a = bool;
// var<uniform> g : [[access(read)]] a; // var<uniform> g : [[access(read)]] a;
auto* a = ty.alias("a", ty.bool_()); auto a = ty.alias("a", ty.bool_());
Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform); Global(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -193,7 +193,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferBoolAlias) {
TEST_F(ResolverStorageClassValidationTest, UniformBufferNoBlockDecoration) { TEST_F(ResolverStorageClassValidationTest, UniformBufferNoBlockDecoration) {
// struct S { x : i32 }; // struct S { x : i32 };
// var<uniform> g : S; // var<uniform> g : S;
auto* s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())}); auto s = Structure(Source{{12, 34}}, "S", {Member("x", ty.i32())});
Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform); Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform);
ASSERT_FALSE(r()->Resolve()); ASSERT_FALSE(r()->Resolve());
@ -207,7 +207,7 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferNoBlockDecoration) {
TEST_F(ResolverStorageClassValidationTest, UniformBufferNoError_Basic) { TEST_F(ResolverStorageClassValidationTest, UniformBufferNoError_Basic) {
// [[block]] struct S { x : i32 }; // [[block]] struct S { x : i32 };
// var<uniform> g : S; // var<uniform> g : S;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform); Global(Source{{56, 78}}, "g", s, ast::StorageClass::kUniform);
@ -218,9 +218,9 @@ TEST_F(ResolverStorageClassValidationTest, UniformBufferNoError_Aliases) {
// [[block]] struct S { x : i32 }; // [[block]] struct S { x : i32 };
// type a1 = S; // type a1 = S;
// var<uniform> g : a1; // var<uniform> g : a1;
auto* s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())}, auto s = Structure("S", {Member(Source{{12, 34}}, "x", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a1 = ty.alias("a1", s); auto a1 = ty.alias("a1", s);
Global(Source{{56, 78}}, "g", a1, ast::StorageClass::kUniform); Global(Source{{56, 78}}, "g", a1, ast::StorageClass::kUniform);
ASSERT_TRUE(r()->Resolve()); ASSERT_TRUE(r()->Resolve());

View File

@ -26,7 +26,7 @@ namespace {
using ResolverStructLayoutTest = ResolverTest; using ResolverStructLayoutTest = ResolverTest;
TEST_F(ResolverStructLayoutTest, Scalars) { TEST_F(ResolverStructLayoutTest, Scalars) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.u32()), Member("b", ty.u32()),
Member("c", ty.i32()), Member("c", ty.i32()),
@ -34,7 +34,7 @@ TEST_F(ResolverStructLayoutTest, Scalars) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 12u); EXPECT_EQ(sem->Size(), 12u);
EXPECT_EQ(sem->SizeNoPadding(), 12u); EXPECT_EQ(sem->SizeNoPadding(), 12u);
@ -52,14 +52,14 @@ TEST_F(ResolverStructLayoutTest, Scalars) {
} }
TEST_F(ResolverStructLayoutTest, Alias) { TEST_F(ResolverStructLayoutTest, Alias) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.alias("a", ty.f32())), Member("a", ty.alias("a", ty.f32())),
Member("b", ty.alias("b", ty.f32())), Member("b", ty.alias("b", ty.f32())),
}); });
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 8u); EXPECT_EQ(sem->Size(), 8u);
EXPECT_EQ(sem->SizeNoPadding(), 8u); EXPECT_EQ(sem->SizeNoPadding(), 8u);
@ -74,7 +74,7 @@ TEST_F(ResolverStructLayoutTest, Alias) {
} }
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayStaticSize) { TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayStaticSize) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.array<i32, 3>()), Member("a", ty.array<i32, 3>()),
Member("b", ty.array<f32, 5>()), Member("b", ty.array<f32, 5>()),
Member("c", ty.array<f32, 1>()), Member("c", ty.array<f32, 1>()),
@ -82,7 +82,7 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayStaticSize) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 36u); EXPECT_EQ(sem->Size(), 36u);
EXPECT_EQ(sem->SizeNoPadding(), 36u); EXPECT_EQ(sem->SizeNoPadding(), 36u);
@ -100,7 +100,7 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayStaticSize) {
} }
TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayStaticSize) { TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayStaticSize) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.array<i32, 3>(/*stride*/ 8)), Member("a", ty.array<i32, 3>(/*stride*/ 8)),
Member("b", ty.array<f32, 5>(/*stride*/ 16)), Member("b", ty.array<f32, 5>(/*stride*/ 16)),
Member("c", ty.array<f32, 1>(/*stride*/ 32)), Member("c", ty.array<f32, 1>(/*stride*/ 32)),
@ -108,7 +108,7 @@ TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayStaticSize) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 136u); EXPECT_EQ(sem->Size(), 136u);
EXPECT_EQ(sem->SizeNoPadding(), 136u); EXPECT_EQ(sem->SizeNoPadding(), 136u);
@ -126,8 +126,7 @@ TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayStaticSize) {
} }
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayRuntimeSized) { TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayRuntimeSized) {
auto* s = auto s = Structure("S",
Structure("S",
{ {
Member("c", ty.array<f32>()), Member("c", ty.array<f32>()),
}, },
@ -135,7 +134,7 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayRuntimeSized) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 4u); EXPECT_EQ(sem->Size(), 4u);
EXPECT_EQ(sem->SizeNoPadding(), 4u); EXPECT_EQ(sem->SizeNoPadding(), 4u);
@ -147,8 +146,7 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayRuntimeSized) {
} }
TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayRuntimeSized) { TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayRuntimeSized) {
auto* s = auto s = Structure("S",
Structure("S",
{ {
Member("c", ty.array<f32>(/*stride*/ 32)), Member("c", ty.array<f32>(/*stride*/ 32)),
}, },
@ -156,7 +154,7 @@ TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayRuntimeSized) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 32u); EXPECT_EQ(sem->Size(), 32u);
EXPECT_EQ(sem->SizeNoPadding(), 32u); EXPECT_EQ(sem->SizeNoPadding(), 32u);
@ -170,13 +168,13 @@ TEST_F(ResolverStructLayoutTest, ExplicitStrideArrayRuntimeSized) {
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfExplicitStrideArray) { TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfExplicitStrideArray) {
auto inner = ty.array<i32, 2>(/*stride*/ 16); // size: 32 auto inner = ty.array<i32, 2>(/*stride*/ 16); // size: 32
auto outer = ty.array(inner, 12); // size: 12 * 32 auto outer = ty.array(inner, 12); // size: 12 * 32
auto* s = Structure("S", { auto s = Structure("S", {
Member("c", outer), Member("c", outer),
}); });
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 384u); EXPECT_EQ(sem->Size(), 384u);
EXPECT_EQ(sem->SizeNoPadding(), 384u); EXPECT_EQ(sem->SizeNoPadding(), 384u);
@ -188,19 +186,19 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfExplicitStrideArray) {
} }
TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfStructure) { TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfStructure) {
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.vec2<i32>()), Member("a", ty.vec2<i32>()),
Member("b", ty.vec3<i32>()), Member("b", ty.vec3<i32>()),
Member("c", ty.vec4<i32>()), Member("c", ty.vec4<i32>()),
}); // size: 48 }); // size: 48
auto outer = ty.array(inner, 12); // size: 12 * 48 auto outer = ty.array(inner, 12); // size: 12 * 48
auto* s = Structure("S", { auto s = Structure("S", {
Member("c", outer), Member("c", outer),
}); });
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 576u); EXPECT_EQ(sem->Size(), 576u);
EXPECT_EQ(sem->SizeNoPadding(), 576u); EXPECT_EQ(sem->SizeNoPadding(), 576u);
@ -212,7 +210,7 @@ TEST_F(ResolverStructLayoutTest, ImplicitStrideArrayOfStructure) {
} }
TEST_F(ResolverStructLayoutTest, Vector) { TEST_F(ResolverStructLayoutTest, Vector) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.vec2<i32>()), Member("a", ty.vec2<i32>()),
Member("b", ty.vec3<i32>()), Member("b", ty.vec3<i32>()),
Member("c", ty.vec4<i32>()), Member("c", ty.vec4<i32>()),
@ -220,7 +218,7 @@ TEST_F(ResolverStructLayoutTest, Vector) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 48u); EXPECT_EQ(sem->Size(), 48u);
EXPECT_EQ(sem->SizeNoPadding(), 48u); EXPECT_EQ(sem->SizeNoPadding(), 48u);
@ -238,7 +236,7 @@ TEST_F(ResolverStructLayoutTest, Vector) {
} }
TEST_F(ResolverStructLayoutTest, Matrix) { TEST_F(ResolverStructLayoutTest, Matrix) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.mat2x2<i32>()), Member("a", ty.mat2x2<i32>()),
Member("b", ty.mat2x3<i32>()), Member("b", ty.mat2x3<i32>()),
Member("c", ty.mat2x4<i32>()), Member("c", ty.mat2x4<i32>()),
@ -252,7 +250,7 @@ TEST_F(ResolverStructLayoutTest, Matrix) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 368u); EXPECT_EQ(sem->Size(), 368u);
EXPECT_EQ(sem->SizeNoPadding(), 368u); EXPECT_EQ(sem->SizeNoPadding(), 368u);
@ -288,10 +286,10 @@ TEST_F(ResolverStructLayoutTest, Matrix) {
} }
TEST_F(ResolverStructLayoutTest, NestedStruct) { TEST_F(ResolverStructLayoutTest, NestedStruct) {
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.mat3x3<i32>()), Member("a", ty.mat3x3<i32>()),
}); });
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", inner), Member("b", inner),
Member("c", ty.i32()), Member("c", ty.i32()),
@ -299,7 +297,7 @@ TEST_F(ResolverStructLayoutTest, NestedStruct) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 80u); EXPECT_EQ(sem->Size(), 80u);
EXPECT_EQ(sem->SizeNoPadding(), 68u); EXPECT_EQ(sem->SizeNoPadding(), 68u);
@ -317,12 +315,12 @@ TEST_F(ResolverStructLayoutTest, NestedStruct) {
} }
TEST_F(ResolverStructLayoutTest, SizeDecorations) { TEST_F(ResolverStructLayoutTest, SizeDecorations) {
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.f32(), {MemberSize(8)}), Member("a", ty.f32(), {MemberSize(8)}),
Member("b", ty.f32(), {MemberSize(16)}), Member("b", ty.f32(), {MemberSize(16)}),
Member("c", ty.f32(), {MemberSize(8)}), Member("c", ty.f32(), {MemberSize(8)}),
}); });
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.f32(), {MemberSize(4)}), Member("a", ty.f32(), {MemberSize(4)}),
Member("b", ty.u32(), {MemberSize(8)}), Member("b", ty.u32(), {MemberSize(8)}),
Member("c", inner), Member("c", inner),
@ -331,7 +329,7 @@ TEST_F(ResolverStructLayoutTest, SizeDecorations) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 76u); EXPECT_EQ(sem->Size(), 76u);
EXPECT_EQ(sem->SizeNoPadding(), 76u); EXPECT_EQ(sem->SizeNoPadding(), 76u);
@ -352,12 +350,12 @@ TEST_F(ResolverStructLayoutTest, SizeDecorations) {
} }
TEST_F(ResolverStructLayoutTest, AlignDecorations) { TEST_F(ResolverStructLayoutTest, AlignDecorations) {
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.f32(), {MemberAlign(8)}), Member("a", ty.f32(), {MemberAlign(8)}),
Member("b", ty.f32(), {MemberAlign(16)}), Member("b", ty.f32(), {MemberAlign(16)}),
Member("c", ty.f32(), {MemberAlign(4)}), Member("c", ty.f32(), {MemberAlign(4)}),
}); });
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.f32(), {MemberAlign(4)}), Member("a", ty.f32(), {MemberAlign(4)}),
Member("b", ty.u32(), {MemberAlign(8)}), Member("b", ty.u32(), {MemberAlign(8)}),
Member("c", inner), Member("c", inner),
@ -366,7 +364,7 @@ TEST_F(ResolverStructLayoutTest, AlignDecorations) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 96u); EXPECT_EQ(sem->Size(), 96u);
EXPECT_EQ(sem->SizeNoPadding(), 68u); EXPECT_EQ(sem->SizeNoPadding(), 68u);
@ -387,13 +385,13 @@ TEST_F(ResolverStructLayoutTest, AlignDecorations) {
} }
TEST_F(ResolverStructLayoutTest, StructWithLotsOfPadding) { TEST_F(ResolverStructLayoutTest, StructWithLotsOfPadding) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32(), {MemberAlign(1024)}), Member("a", ty.i32(), {MemberAlign(1024)}),
}); });
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_EQ(sem->Size(), 1024u); EXPECT_EQ(sem->Size(), 1024u);
EXPECT_EQ(sem->SizeNoPadding(), 4u); EXPECT_EQ(sem->SizeNoPadding(), 4u);

View File

@ -28,41 +28,41 @@ namespace {
using ResolverPipelineStageUseTest = ResolverTest; using ResolverPipelineStageUseTest = ResolverTest;
TEST_F(ResolverPipelineStageUseTest, UnusedStruct) { TEST_F(ResolverPipelineStageUseTest, UnusedStruct) {
auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->PipelineStageUses().empty()); EXPECT_TRUE(sem->PipelineStageUses().empty());
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointParam) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointParam) {
auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
Func("foo", {Param("param", s)}, ty.void_(), {}, {}); Func("foo", {Param("param", s)}, ty.void_(), {}, {});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->PipelineStageUses().empty()); EXPECT_TRUE(sem->PipelineStageUses().empty());
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointReturnType) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsNonEntryPointReturnType) {
auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
Func("foo", {}, s, {Return(Construct(s, Expr(0.f)))}, {}); Func("foo", {}, s, {Return(Construct(s, Expr(0.f)))}, {});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->PipelineStageUses().empty()); EXPECT_TRUE(sem->PipelineStageUses().empty());
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderParam) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderParam) {
auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
Func("main", {Param("param", s)}, ty.vec4<f32>(), Func("main", {Param("param", s)}, ty.vec4<f32>(),
{Return(Construct(ty.vec4<f32>()))}, {Return(Construct(ty.vec4<f32>()))},
@ -71,14 +71,14 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderParam) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(), EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(sem::PipelineStageUsage::kVertexInput)); UnorderedElementsAre(sem::PipelineStageUsage::kVertexInput));
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderReturnType) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderReturnType) {
auto* s = Structure( auto s = Structure(
"S", {Member("a", ty.f32(), {Builtin(ast::Builtin::kPosition)})}); "S", {Member("a", ty.f32(), {Builtin(ast::Builtin::kPosition)})});
Func("main", {}, s, {Return(Construct(s, Expr(0.f)))}, Func("main", {}, s, {Return(Construct(s, Expr(0.f)))},
@ -86,42 +86,42 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsVertexShaderReturnType) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(), EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(sem::PipelineStageUsage::kVertexOutput)); UnorderedElementsAre(sem::PipelineStageUsage::kVertexOutput));
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderParam) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderParam) {
auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
Func("main", {Param("param", s)}, ty.void_(), {}, Func("main", {Param("param", s)}, ty.void_(), {},
{Stage(ast::PipelineStage::kFragment)}); {Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(), EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(sem::PipelineStageUsage::kFragmentInput)); UnorderedElementsAre(sem::PipelineStageUsage::kFragmentInput));
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderReturnType) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsFragmentShaderReturnType) {
auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
Func("main", {}, s, {Return(Construct(s, Expr(0.f)))}, Func("main", {}, s, {Return(Construct(s, Expr(0.f)))},
{Stage(ast::PipelineStage::kFragment)}); {Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(), EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(sem::PipelineStageUsage::kFragmentOutput)); UnorderedElementsAre(sem::PipelineStageUsage::kFragmentOutput));
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedAsComputeShaderParam) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsComputeShaderParam) {
auto* s = Structure( auto s = Structure(
"S", "S",
{Member("a", ty.u32(), {Builtin(ast::Builtin::kLocalInvocationIndex)})}); {Member("a", ty.u32(), {Builtin(ast::Builtin::kLocalInvocationIndex)})});
@ -130,14 +130,14 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsComputeShaderParam) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(), EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(sem::PipelineStageUsage::kComputeInput)); UnorderedElementsAre(sem::PipelineStageUsage::kComputeInput));
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) { TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) {
auto* s = Structure( auto s = Structure(
"S", {Member("a", ty.f32(), {Builtin(ast::Builtin::kPosition)})}); "S", {Member("a", ty.f32(), {Builtin(ast::Builtin::kPosition)})});
Func("vert_main", {Param("param", s)}, s, {Return(Construct(s, Expr(0.f)))}, Func("vert_main", {Param("param", s)}, s, {Return(Construct(s, Expr(0.f)))},
@ -148,7 +148,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) {
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(), EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(sem::PipelineStageUsage::kVertexInput, UnorderedElementsAre(sem::PipelineStageUsage::kVertexInput,
@ -157,30 +157,30 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedMultipleStages) {
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamViaAlias) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderParamViaAlias) {
auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
auto* s_alias = ty.alias("S_alias", s); auto s_alias = ty.alias("S_alias", s);
Func("main", {Param("param", s_alias)}, ty.void_(), {}, Func("main", {Param("param", s_alias)}, ty.void_(), {},
{Stage(ast::PipelineStage::kFragment)}); {Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(), EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(sem::PipelineStageUsage::kFragmentInput)); UnorderedElementsAre(sem::PipelineStageUsage::kFragmentInput));
} }
TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeViaAlias) { TEST_F(ResolverPipelineStageUseTest, StructUsedAsShaderReturnTypeViaAlias) {
auto* s = Structure("S", {Member("a", ty.f32(), {Location(0)})}); auto s = Structure("S", {Member("a", ty.f32(), {Location(0)})});
auto* s_alias = ty.alias("S_alias", s); auto s_alias = ty.alias("S_alias", s);
Func("main", {}, s_alias, {Return(Construct(s_alias, Expr(0.f)))}, Func("main", {}, s_alias, {Return(Construct(s_alias, Expr(0.f)))},
{Stage(ast::PipelineStage::kFragment)}); {Stage(ast::PipelineStage::kFragment)});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->PipelineStageUses(), EXPECT_THAT(sem->PipelineStageUses(),
UnorderedElementsAre(sem::PipelineStageUsage::kFragmentOutput)); UnorderedElementsAre(sem::PipelineStageUsage::kFragmentOutput));

View File

@ -28,156 +28,156 @@ namespace {
using ResolverStorageClassUseTest = ResolverTest; using ResolverStorageClassUseTest = ResolverTest;
TEST_F(ResolverStorageClassUseTest, UnreachableStruct) { TEST_F(ResolverStorageClassUseTest, UnreachableStruct) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_TRUE(sem->StorageClassUsage().empty()); EXPECT_TRUE(sem->StorageClassUsage().empty());
} }
TEST_F(ResolverStorageClassUseTest, StructReachableFromParameter) { TEST_F(ResolverStorageClassUseTest, StructReachableFromParameter) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
Func("f", {Param("param", s)}, ty.void_(), {}, {}); Func("f", {Param("param", s)}, ty.void_(), {}, {});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kNone)); UnorderedElementsAre(ast::StorageClass::kNone));
} }
TEST_F(ResolverStorageClassUseTest, StructReachableFromReturnType) { TEST_F(ResolverStorageClassUseTest, StructReachableFromReturnType) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
Func("f", {}, s, {Return(Construct(s))}, {}); Func("f", {}, s, {Return(Construct(s))}, {});
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kNone)); UnorderedElementsAre(ast::StorageClass::kNone));
} }
TEST_F(ResolverStorageClassUseTest, StructReachableFromGlobal) { TEST_F(ResolverStorageClassUseTest, StructReachableFromGlobal) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
Global("g", s, ast::StorageClass::kPrivate); Global("g", s, ast::StorageClass::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kPrivate)); UnorderedElementsAre(ast::StorageClass::kPrivate));
} }
TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalAlias) { TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalAlias) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
auto* a = ty.alias("A", s); auto a = ty.alias("A", s);
Global("g", a, ast::StorageClass::kPrivate); Global("g", a, ast::StorageClass::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kPrivate)); UnorderedElementsAre(ast::StorageClass::kPrivate));
} }
TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalStruct) { TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalStruct) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
auto* o = Structure("O", {Member("a", s)}); auto o = Structure("O", {Member("a", s)});
Global("g", o, ast::StorageClass::kPrivate); Global("g", o, ast::StorageClass::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kPrivate)); UnorderedElementsAre(ast::StorageClass::kPrivate));
} }
TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalArray) { TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalArray) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
auto a = ty.array(s, 3); auto a = ty.array(s, 3);
Global("g", a, ast::StorageClass::kPrivate); Global("g", a, ast::StorageClass::kPrivate);
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kPrivate)); UnorderedElementsAre(ast::StorageClass::kPrivate));
} }
TEST_F(ResolverStorageClassUseTest, StructReachableFromLocal) { TEST_F(ResolverStorageClassUseTest, StructReachableFromLocal) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
WrapInFunction(Var("g", s, ast::StorageClass::kFunction)); WrapInFunction(Var("g", s, ast::StorageClass::kFunction));
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kFunction)); UnorderedElementsAre(ast::StorageClass::kFunction));
} }
TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalAlias) { TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalAlias) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
auto* a = ty.alias("A", s); auto a = ty.alias("A", s);
WrapInFunction(Var("g", a, ast::StorageClass::kFunction)); WrapInFunction(Var("g", a, ast::StorageClass::kFunction));
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kFunction)); UnorderedElementsAre(ast::StorageClass::kFunction));
} }
TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalStruct) { TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalStruct) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
auto* o = Structure("O", {Member("a", s)}); auto o = Structure("O", {Member("a", s)});
WrapInFunction(Var("g", o, ast::StorageClass::kFunction)); WrapInFunction(Var("g", o, ast::StorageClass::kFunction));
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kFunction)); UnorderedElementsAre(ast::StorageClass::kFunction));
} }
TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalArray) { TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalArray) {
auto* s = Structure("S", {Member("a", ty.f32())}); auto s = Structure("S", {Member("a", ty.f32())});
auto a = ty.array(s, 3); auto a = ty.array(s, 3);
WrapInFunction(Var("g", a, ast::StorageClass::kFunction)); WrapInFunction(Var("g", a, ast::StorageClass::kFunction));
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kFunction)); UnorderedElementsAre(ast::StorageClass::kFunction));
} }
TEST_F(ResolverStorageClassUseTest, StructMultipleStorageClassUses) { TEST_F(ResolverStorageClassUseTest, StructMultipleStorageClassUses) {
auto* s = Structure("S", {Member("a", ty.f32())}, auto s = Structure("S", {Member("a", ty.f32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("x", s, ast::StorageClass::kUniform); Global("x", s, ast::StorageClass::kUniform);
Global("y", ac, ast::StorageClass::kStorage); Global("y", ac, ast::StorageClass::kStorage);
WrapInFunction(Var("g", s, ast::StorageClass::kFunction)); WrapInFunction(Var("g", s, ast::StorageClass::kFunction));
ASSERT_TRUE(r()->Resolve()) << r()->error(); ASSERT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(s); auto* sem = Sem().Get(s.sem);
ASSERT_NE(sem, nullptr); ASSERT_NE(sem, nullptr);
EXPECT_THAT(sem->StorageClassUsage(), EXPECT_THAT(sem->StorageClassUsage(),
UnorderedElementsAre(ast::StorageClass::kUniform, UnorderedElementsAre(ast::StorageClass::kUniform,

View File

@ -66,7 +66,7 @@ TEST_P(InferTypeTest_FromConstructorExpression, All) {
// } // }
auto& params = GetParam(); auto& params = GetParam();
auto* rhs_type = params.create_rhs_type(ty); auto rhs_type = params.create_rhs_type(ty);
auto* constructor_expr = ConstructValueFilledWith(rhs_type, 0); auto* constructor_expr = ConstructValueFilledWith(rhs_type, 0);
auto sc = ast::StorageClass::kFunction; auto sc = ast::StorageClass::kFunction;
@ -114,7 +114,7 @@ TEST_P(InferTypeTest_FromArithmeticExpression, All) {
// } // }
auto& params = GetParam(); auto& params = GetParam();
auto* rhs_type = params.create_rhs_type(ty); auto rhs_type = params.create_rhs_type(ty);
auto* arith_lhs_expr = ConstructValueFilledWith(rhs_type, 2); auto* arith_lhs_expr = ConstructValueFilledWith(rhs_type, 2);
auto* arith_rhs_expr = ConstructValueFilledWith(ElementTypeOf(rhs_type), 3); auto* arith_rhs_expr = ConstructValueFilledWith(ElementTypeOf(rhs_type), 3);
@ -159,7 +159,7 @@ TEST_P(InferTypeTest_FromCallExpression, All) {
// } // }
auto& params = GetParam(); auto& params = GetParam();
auto* rhs_type = params.create_rhs_type(ty); auto rhs_type = params.create_rhs_type(ty);
Func("foo", {}, rhs_type, {Return(ConstructValueFilledWith(rhs_type, 0))}, Func("foo", {}, rhs_type, {Return(ConstructValueFilledWith(rhs_type, 0))},
{}); {});

View File

@ -400,7 +400,7 @@ TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsNotLast_Fail) {
// a: u32; // a: u32;
//} //}
auto* alias = ty.alias("RTArr", ty.array<u32>()); auto alias = ty.alias("RTArr", ty.array<u32>());
Structure("s", Structure("s",
{ {
@ -426,7 +426,7 @@ TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsLast_Pass) {
// b: RTArr; // b: RTArr;
//} //}
auto* alias = ty.alias("RTArr", ty.array<u32>()); auto alias = ty.alias("RTArr", ty.array<u32>());
Structure("s", Structure("s",
{ {
@ -478,8 +478,8 @@ using CanonicalTest = ResolverTestWithParam<Params>;
TEST_P(CanonicalTest, All) { TEST_P(CanonicalTest, All) {
auto& params = GetParam(); auto& params = GetParam();
auto* type = params.create_type(ty); auto type = params.create_type(ty);
auto* expected_canonical_type = params.create_canonical_type(ty); auto expected_canonical_type = params.create_canonical_type(ty);
auto* canonical_type = r()->Canonical(type); auto* canonical_type = r()->Canonical(type);
@ -508,7 +508,7 @@ static constexpr DimensionParams dimension_cases[] = {
using MultisampledTextureDimensionTest = ResolverTestWithParam<DimensionParams>; using MultisampledTextureDimensionTest = ResolverTestWithParam<DimensionParams>;
TEST_P(MultisampledTextureDimensionTest, All) { TEST_P(MultisampledTextureDimensionTest, All) {
auto& params = GetParam(); auto& params = GetParam();
Global("a", create<sem::MultisampledTexture>(params.dim, ty.i32()), Global("a", ty.multisampled_texture(params.dim, ty.i32()),
ast::StorageClass::kUniformConstant, nullptr, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
@ -550,9 +550,9 @@ static constexpr TypeParams type_cases[] = {
using MultisampledTextureTypeTest = ResolverTestWithParam<TypeParams>; using MultisampledTextureTypeTest = ResolverTestWithParam<TypeParams>;
TEST_P(MultisampledTextureTypeTest, All) { TEST_P(MultisampledTextureTypeTest, All) {
auto& params = GetParam(); auto& params = GetParam();
Global("a", Global(
create<sem::MultisampledTexture>(ast::TextureDimension::k2d, "a",
params.type_func(ty)), ty.multisampled_texture(ast::TextureDimension::k2d, params.type_func(ty)),
ast::StorageClass::kUniformConstant, nullptr, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
@ -588,10 +588,7 @@ static constexpr DimensionParams Dimension_cases[] = {
using StorageTextureDimensionTest = ResolverTestWithParam<DimensionParams>; using StorageTextureDimensionTest = ResolverTestWithParam<DimensionParams>;
TEST_P(StorageTextureDimensionTest, All) { TEST_P(StorageTextureDimensionTest, All) {
auto& params = GetParam(); auto& params = GetParam();
Global("a", Global("a", ty.storage_texture(params.dim, ast::ImageFormat::kR32Uint),
create<sem::StorageTexture>(params.dim, ast::ImageFormat::kR32Uint,
sem::StorageTexture::SubtypeFor(
ast::ImageFormat::kR32Uint, Types())),
ast::StorageClass::kUniformConstant, nullptr, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
@ -660,20 +657,14 @@ TEST_P(StorageTextureFormatTest, All) {
// var d : texture_storage_3<*>; // var d : texture_storage_3<*>;
// } // }
Global("a", Global("a", ty.storage_texture(ast::TextureDimension::k1d, params.format),
create<sem::StorageTexture>(
ast::TextureDimension::k1d, params.format,
sem::StorageTexture::SubtypeFor(params.format, Types())),
ast::StorageClass::kUniformConstant, nullptr, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
}); });
Global("b", Global("b", ty.storage_texture(ast::TextureDimension::k2d, params.format),
create<sem::StorageTexture>(
ast::TextureDimension::k2d, params.format,
sem::StorageTexture::SubtypeFor(params.format, Types())),
ast::StorageClass::kUniformConstant, nullptr, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(1), create<ast::BindingDecoration>(1),
@ -681,19 +672,14 @@ TEST_P(StorageTextureFormatTest, All) {
}); });
Global("c", Global("c",
create<sem::StorageTexture>( ty.storage_texture(ast::TextureDimension::k2dArray, params.format),
ast::TextureDimension::k2dArray, params.format,
sem::StorageTexture::SubtypeFor(params.format, Types())),
ast::StorageClass::kUniformConstant, nullptr, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(2), create<ast::BindingDecoration>(2),
create<ast::GroupDecoration>(0), create<ast::GroupDecoration>(0),
}); });
Global("d", Global("d", ty.storage_texture(ast::TextureDimension::k3d, params.format),
create<sem::StorageTexture>(
ast::TextureDimension::k3d, params.format,
sem::StorageTexture::SubtypeFor(params.format, Types())),
ast::StorageClass::kUniformConstant, nullptr, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(3), create<ast::BindingDecoration>(3),

View File

@ -164,7 +164,7 @@ TEST_F(ResolverValidationTest,
TEST_F(ResolverValidationTest, TEST_F(ResolverValidationTest,
Stmt_VariableDecl_MismatchedTypeScalarConstructor_Alias) { Stmt_VariableDecl_MismatchedTypeScalarConstructor_Alias) {
auto* my_int = ty.alias("MyInt", ty.i32()); auto my_int = ty.alias("MyInt", ty.i32());
u32 unsigned_value = 2u; // Type does not match variable type u32 unsigned_value = 2u; // Type does not match variable type
auto* var = auto* var =
Var("my_var", my_int, ast::StorageClass::kNone, Expr(unsigned_value)); Var("my_var", my_int, ast::StorageClass::kNone, Expr(unsigned_value));
@ -1684,7 +1684,7 @@ TEST_F(ResolverValidationTest,
} }
TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Error) { TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Error) {
auto* alias = ty.alias("UnsignedInt", ty.u32()); auto alias = ty.alias("UnsignedInt", ty.u32());
Global("uint_var", alias, ast::StorageClass::kInput); Global("uint_var", alias, ast::StorageClass::kInput);
auto* tc = vec2<f32>(Expr(Source{{12, 34}}, "uint_var")); auto* tc = vec2<f32>(Expr(Source{{12, 34}}, "uint_var"));
@ -1697,8 +1697,8 @@ TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Error) {
} }
TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) { TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) {
auto* f32_alias = ty.alias("Float32", ty.f32()); auto f32_alias = ty.alias("Float32", ty.f32());
auto* vec2_alias = ty.alias("VectorFloat2", ty.vec2<f32>()); auto vec2_alias = ty.alias("VectorFloat2", ty.vec2<f32>());
Global("my_f32", f32_alias, ast::StorageClass::kInput); Global("my_f32", f32_alias, ast::StorageClass::kInput);
Global("my_vec2", vec2_alias, ast::StorageClass::kInput); Global("my_vec2", vec2_alias, ast::StorageClass::kInput);
@ -1708,7 +1708,7 @@ TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) {
} }
TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ElementTypeAlias_Error) { TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ElementTypeAlias_Error) {
auto* f32_alias = ty.alias("Float32", ty.f32()); auto f32_alias = ty.alias("Float32", ty.f32());
auto* vec_type = create<sem::Vector>(f32_alias, 2); auto* vec_type = create<sem::Vector>(f32_alias, 2);
// vec2<Float32>(1.0f, 1u) // vec2<Float32>(1.0f, 1u)
@ -1726,7 +1726,7 @@ TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ElementTypeAlias_Error) {
TEST_F(ResolverValidationTest, TEST_F(ResolverValidationTest,
Expr_Constructor_Vector_ElementTypeAlias_Success) { Expr_Constructor_Vector_ElementTypeAlias_Success) {
auto* f32_alias = ty.alias("Float32", ty.f32()); auto f32_alias = ty.alias("Float32", ty.f32());
auto* vec_type = create<sem::Vector>(f32_alias, 2); auto* vec_type = create<sem::Vector>(f32_alias, 2);
// vec2<Float32>(1.0f, 1.0f) // vec2<Float32>(1.0f, 1.0f)
@ -1739,7 +1739,7 @@ TEST_F(ResolverValidationTest,
TEST_F(ResolverValidationTest, TEST_F(ResolverValidationTest,
Expr_Constructor_Vector_ArgumentElementTypeAlias_Error) { Expr_Constructor_Vector_ArgumentElementTypeAlias_Error) {
auto* f32_alias = ty.alias("Float32", ty.f32()); auto f32_alias = ty.alias("Float32", ty.f32());
auto* vec_type = create<sem::Vector>(f32_alias, 2); auto* vec_type = create<sem::Vector>(f32_alias, 2);
// vec3<u32>(vec<Float32>(), 1.0f) // vec3<u32>(vec<Float32>(), 1.0f)
@ -1756,7 +1756,7 @@ TEST_F(ResolverValidationTest,
TEST_F(ResolverValidationTest, TEST_F(ResolverValidationTest,
Expr_Constructor_Vector_ArgumentElementTypeAlias_Success) { Expr_Constructor_Vector_ArgumentElementTypeAlias_Success) {
auto* f32_alias = ty.alias("Float32", ty.f32()); auto f32_alias = ty.alias("Float32", ty.f32());
auto* vec_type = create<sem::Vector>(f32_alias, 2); auto* vec_type = create<sem::Vector>(f32_alias, 2);
// vec3<f32>(vec<Float32>(), 1.0f) // vec3<f32>(vec<Float32>(), 1.0f)
@ -1789,8 +1789,8 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_Error_TooFewArguments) {
// matNxM<f32>(vecM<f32>(), ...); with N - 1 arguments // matNxM<f32>(vecM<f32>(), ...); with N - 1 arguments
const auto param = GetParam(); const auto param = GetParam();
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* vec_type = create<sem::Vector>(ty.f32(), param.rows); auto vec_type = ty.vec<f32>(param.rows);
ast::ExpressionList args; ast::ExpressionList args;
for (uint32_t i = 1; i <= param.columns - 1; i++) { for (uint32_t i = 1; i <= param.columns - 1; i++) {
@ -1813,8 +1813,8 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_Error_TooManyArguments) {
// matNxM<f32>(vecM<f32>(), ...); with N + 1 arguments // matNxM<f32>(vecM<f32>(), ...); with N + 1 arguments
const auto param = GetParam(); const auto param = GetParam();
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* vec_type = create<sem::Vector>(ty.f32(), param.rows); auto vec_type = ty.vec<f32>(param.rows);
ast::ExpressionList args; ast::ExpressionList args;
for (uint32_t i = 1; i <= param.columns + 1; i++) { for (uint32_t i = 1; i <= param.columns + 1; i++) {
@ -1837,7 +1837,7 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_Error_InvalidArgumentType) {
// matNxM<f32>(1.0, 1.0, ...); N arguments // matNxM<f32>(1.0, 1.0, ...); N arguments
const auto param = GetParam(); const auto param = GetParam();
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
ast::ExpressionList args; ast::ExpressionList args;
for (uint32_t i = 1; i <= param.columns; i++) { for (uint32_t i = 1; i <= param.columns; i++) {
@ -1866,9 +1866,9 @@ TEST_P(MatrixConstructorTest,
return; return;
} }
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* valid_vec_type = create<sem::Vector>(ty.f32(), param.rows); auto valid_vec_type = ty.vec<f32>(param.rows);
auto* invalid_vec_type = create<sem::Vector>(ty.f32(), param.rows - 1); auto invalid_vec_type = ty.vec<f32>(param.rows - 1);
ast::ExpressionList args; ast::ExpressionList args;
for (uint32_t i = 1; i <= param.columns - 1; i++) { for (uint32_t i = 1; i <= param.columns - 1; i++) {
@ -1902,9 +1902,9 @@ TEST_P(MatrixConstructorTest,
return; return;
} }
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* valid_vec_type = create<sem::Vector>(ty.f32(), param.rows); auto valid_vec_type = ty.vec<f32>(param.rows);
auto* invalid_vec_type = create<sem::Vector>(ty.f32(), param.rows + 1); auto invalid_vec_type = ty.vec<f32>(param.rows + 1);
ast::ExpressionList args; ast::ExpressionList args;
for (uint32_t i = 1; i <= param.columns - 1; i++) { for (uint32_t i = 1; i <= param.columns - 1; i++) {
@ -1932,7 +1932,7 @@ TEST_P(MatrixConstructorTest,
// matNxM<f32>(vecM<u32>(), ...); with N arguments // matNxM<f32>(vecM<u32>(), ...); with N arguments
const auto param = GetParam(); const auto param = GetParam();
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* vec_type = create<sem::Vector>(ty.u32(), param.rows); auto* vec_type = create<sem::Vector>(ty.u32(), param.rows);
ast::ExpressionList args; ast::ExpressionList args;
@ -1956,7 +1956,7 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ZeroValue_Success) {
// matNxM<f32>(); // matNxM<f32>();
const auto param = GetParam(); const auto param = GetParam();
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* tc = create<ast::TypeConstructorExpression>(Source{{12, 40}}, auto* tc = create<ast::TypeConstructorExpression>(Source{{12, 40}},
matrix_type, ExprList()); matrix_type, ExprList());
WrapInFunction(tc); WrapInFunction(tc);
@ -1968,8 +1968,8 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_WithArguments_Success) {
// matNxM<f32>(vecM<f32>(), ...); with N arguments // matNxM<f32>(vecM<f32>(), ...); with N arguments
const auto param = GetParam(); const auto param = GetParam();
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* vec_type = create<sem::Vector>(ty.f32(), param.rows); auto vec_type = ty.vec<f32>(param.rows);
ast::ExpressionList args; ast::ExpressionList args;
for (uint32_t i = 1; i <= param.columns; i++) { for (uint32_t i = 1; i <= param.columns; i++) {
@ -1988,8 +1988,8 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Error) {
// matNxM<Float32>(vecM<u32>(), ...); with N arguments // matNxM<Float32>(vecM<u32>(), ...); with N arguments
const auto param = GetParam(); const auto param = GetParam();
auto* f32_alias = ty.alias("Float32", ty.f32()); auto f32_alias = ty.alias("Float32", ty.f32());
auto* matrix_type = create<sem::Matrix>(f32_alias, param.rows, param.columns); auto matrix_type = ty.mat(f32_alias, param.columns, param.rows);
auto* vec_type = create<sem::Vector>(ty.u32(), param.rows); auto* vec_type = create<sem::Vector>(ty.u32(), param.rows);
ast::ExpressionList args; ast::ExpressionList args;
@ -2013,9 +2013,9 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Success) {
// matNxM<Float32>(vecM<f32>(), ...); with N arguments // matNxM<Float32>(vecM<f32>(), ...); with N arguments
const auto param = GetParam(); const auto param = GetParam();
auto* f32_alias = ty.alias("Float32", ty.f32()); auto f32_alias = ty.alias("Float32", ty.f32());
auto* matrix_type = create<sem::Matrix>(f32_alias, param.rows, param.columns); auto matrix_type = ty.mat(f32_alias, param.columns, param.rows);
auto* vec_type = create<sem::Vector>(ty.f32(), param.rows); auto vec_type = ty.vec<f32>(param.rows);
ast::ExpressionList args; ast::ExpressionList args;
for (uint32_t i = 1; i <= param.columns; i++) { for (uint32_t i = 1; i <= param.columns; i++) {
@ -2031,7 +2031,7 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Success) {
} }
TEST_F(ResolverValidationTest, Expr_MatrixConstructor_ArgumentTypeAlias_Error) { TEST_F(ResolverValidationTest, Expr_MatrixConstructor_ArgumentTypeAlias_Error) {
auto* vec2_alias = ty.alias("VectorUnsigned2", ty.vec2<u32>()); auto vec2_alias = ty.alias("VectorUnsigned2", ty.vec2<u32>());
auto* tc = mat2x2<f32>(create<ast::TypeConstructorExpression>( auto* tc = mat2x2<f32>(create<ast::TypeConstructorExpression>(
Source{{12, 34}}, vec2_alias, ExprList()), Source{{12, 34}}, vec2_alias, ExprList()),
vec2<f32>()); vec2<f32>());
@ -2045,9 +2045,9 @@ TEST_F(ResolverValidationTest, Expr_MatrixConstructor_ArgumentTypeAlias_Error) {
TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) { TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) {
const auto param = GetParam(); const auto param = GetParam();
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* vec_type = create<sem::Vector>(ty.f32(), param.rows); auto vec_type = ty.vec<f32>(param.rows);
auto* vec_alias = ty.alias("VectorFloat2", vec_type); auto vec_alias = ty.alias("VectorFloat2", vec_type);
ast::ExpressionList args; ast::ExpressionList args;
for (uint32_t i = 1; i <= param.columns; i++) { for (uint32_t i = 1; i <= param.columns; i++) {
@ -2064,8 +2064,8 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) {
TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Error) { TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Error) {
const auto param = GetParam(); const auto param = GetParam();
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* f32_alias = ty.alias("UnsignedInt", ty.u32()); auto f32_alias = ty.alias("UnsignedInt", ty.u32());
auto* vec_type = create<sem::Vector>(f32_alias, param.rows); auto* vec_type = create<sem::Vector>(f32_alias, param.rows);
ast::ExpressionList args; ast::ExpressionList args;
@ -2088,8 +2088,8 @@ TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Error) {
TEST_P(MatrixConstructorTest, TEST_P(MatrixConstructorTest,
Expr_Constructor_ArgumentElementTypeAlias_Success) { Expr_Constructor_ArgumentElementTypeAlias_Success) {
const auto param = GetParam(); const auto param = GetParam();
auto* matrix_type = create<sem::Matrix>(ty.f32(), param.rows, param.columns); auto matrix_type = ty.mat<f32>(param.columns, param.rows);
auto* f32_alias = ty.alias("Float32", ty.f32()); auto f32_alias = ty.alias("Float32", ty.f32());
auto* vec_type = create<sem::Vector>(f32_alias, param.rows); auto* vec_type = create<sem::Vector>(f32_alias, param.rows);
ast::ExpressionList args; ast::ExpressionList args;

View File

@ -23,13 +23,13 @@ namespace {
using AliasTest = TestHelper; using AliasTest = TestHelper;
TEST_F(AliasTest, Create) { TEST_F(AliasTest, Create) {
auto* a = ty.alias("a_type", ty.u32()); auto* a = create<Alias>(Sym("a_type"), ty.u32());
EXPECT_EQ(a->symbol(), Symbol(1, ID())); EXPECT_EQ(a->symbol(), Symbol(1, ID()));
EXPECT_EQ(a->type(), ty.u32()); EXPECT_EQ(a->type(), ty.u32());
} }
TEST_F(AliasTest, Is) { TEST_F(AliasTest, Is) {
auto* at = ty.alias("a", ty.i32()); auto* at = create<Alias>(Sym("a"), ty.i32());
sem::Type* ty = at; sem::Type* ty = at;
EXPECT_FALSE(ty->Is<AccessControl>()); EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_TRUE(ty->Is<Alias>()); EXPECT_TRUE(ty->Is<Alias>());
@ -47,17 +47,17 @@ TEST_F(AliasTest, Is) {
} }
TEST_F(AliasTest, TypeName) { TEST_F(AliasTest, TypeName) {
auto* at = ty.alias("Particle", ty.i32()); auto* at = create<Alias>(Sym("Particle"), ty.i32());
EXPECT_EQ(at->type_name(), "__alias_$1__i32"); EXPECT_EQ(at->type_name(), "__alias_$1__i32");
} }
TEST_F(AliasTest, FriendlyName) { TEST_F(AliasTest, FriendlyName) {
auto* at = ty.alias("Particle", ty.i32()); auto* at = create<Alias>(Sym("Particle"), ty.i32());
EXPECT_EQ(at->FriendlyName(Symbols()), "Particle"); EXPECT_EQ(at->FriendlyName(Symbols()), "Particle");
} }
TEST_F(AliasTest, UnwrapIfNeeded_Alias) { TEST_F(AliasTest, UnwrapIfNeeded_Alias) {
auto* a = ty.alias("a_type", ty.u32()); auto* a = create<Alias>(Sym("a_type"), ty.u32());
EXPECT_EQ(a->symbol(), Symbol(1, ID())); EXPECT_EQ(a->symbol(), Symbol(1, ID()));
EXPECT_EQ(a->type(), ty.u32()); EXPECT_EQ(a->type(), ty.u32());
EXPECT_EQ(a->UnwrapIfNeeded(), ty.u32()); EXPECT_EQ(a->UnwrapIfNeeded(), ty.u32());
@ -65,14 +65,14 @@ TEST_F(AliasTest, UnwrapIfNeeded_Alias) {
} }
TEST_F(AliasTest, UnwrapIfNeeded_AccessControl) { TEST_F(AliasTest, UnwrapIfNeeded_AccessControl) {
AccessControl a{ast::AccessControl::kReadOnly, ty.u32()}; auto* a = create<AccessControl>(ast::AccessControl::kReadOnly, ty.u32());
EXPECT_EQ(a.type(), ty.u32()); EXPECT_EQ(a->type(), ty.u32());
EXPECT_EQ(a.UnwrapIfNeeded(), ty.u32()); EXPECT_EQ(a->UnwrapIfNeeded(), ty.u32());
} }
TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel) { TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel) {
auto* a = ty.alias("a_type", ty.u32()); auto* a = create<Alias>(Sym("a_type"), ty.u32());
auto* aa = ty.alias("aa_type", a); auto* aa = create<Alias>(Sym("aa_type"), a);
EXPECT_EQ(aa->symbol(), Symbol(2, ID())); EXPECT_EQ(aa->symbol(), Symbol(2, ID()));
EXPECT_EQ(aa->type(), a); EXPECT_EQ(aa->type(), a);
@ -80,19 +80,19 @@ TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel) {
} }
TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel_AliasAccessControl) { TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel_AliasAccessControl) {
auto* a = ty.alias("a_type", ty.u32()); auto* a = create<Alias>(Sym("a_type"), ty.u32());
auto* aa = create<AccessControl>(ast::AccessControl::kReadWrite, a);
AccessControl aa{ast::AccessControl::kReadWrite, a}; EXPECT_EQ(aa->type(), a);
EXPECT_EQ(aa.type(), a); EXPECT_EQ(aa->UnwrapIfNeeded(), ty.u32());
EXPECT_EQ(aa.UnwrapIfNeeded(), ty.u32());
} }
TEST_F(AliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) { TEST_F(AliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) {
auto* a = ty.alias("a_type", ty.u32()); auto* u32 = create<U32>();
auto* aa = ty.alias("aa_type", a); auto* a = create<Alias>(Sym(Sym("a_type")), u32);
Pointer paa{aa, ast::StorageClass::kUniform}; auto* aa = create<Alias>(Sym("aa_type"), a);
auto* apaa = ty.alias("paa_type", &paa); auto* paa = create<Pointer>(aa, ast::StorageClass::kUniform);
auto* aapaa = ty.alias("aapaa_type", apaa); auto* apaa = create<Alias>(Sym("paa_type"), paa);
auto* aapaa = create<Alias>(Sym("aapaa_type"), apaa);
EXPECT_EQ(aapaa->symbol(), Symbol(4, ID())); EXPECT_EQ(aapaa->symbol(), Symbol(4, ID()));
EXPECT_EQ(aapaa->type(), apaa); EXPECT_EQ(aapaa->type(), apaa);
@ -100,47 +100,47 @@ TEST_F(AliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) {
} }
TEST_F(AliasTest, UnwrapAll_SecondConsecutivePointerBlocksUnrapping) { TEST_F(AliasTest, UnwrapAll_SecondConsecutivePointerBlocksUnrapping) {
auto* a = ty.alias("a_type", ty.u32()); auto* a = create<Alias>(Sym("a_type"), ty.u32());
auto* aa = ty.alias("aa_type", a); auto* aa = create<Alias>(Sym("aa_type"), a);
Pointer paa{aa, ast::StorageClass::kUniform}; auto* paa = create<Pointer>(aa, ast::StorageClass::kUniform);
Pointer ppaa{&paa, ast::StorageClass::kUniform}; auto* ppaa = create<Pointer>(paa, ast::StorageClass::kUniform);
auto* appaa = ty.alias("appaa_type", &ppaa); auto* appaa = create<Alias>(Sym("appaa_type"), ppaa);
EXPECT_EQ(appaa->UnwrapAll(), &paa); EXPECT_EQ(appaa->UnwrapAll(), paa);
} }
TEST_F(AliasTest, UnwrapAll_SecondNonConsecutivePointerBlocksUnrapping) { TEST_F(AliasTest, UnwrapAll_SecondNonConsecutivePointerBlocksUnrapping) {
auto* a = ty.alias("a_type", ty.u32()); auto* a = create<Alias>(Sym("a_type"), ty.u32());
auto* aa = ty.alias("aa_type", a); auto* aa = create<Alias>(Sym("aa_type"), a);
Pointer paa{aa, ast::StorageClass::kUniform}; auto* paa = create<Pointer>(aa, ast::StorageClass::kUniform);
auto* apaa = ty.alias("apaa_type", &paa); auto* apaa = create<Alias>(Sym("apaa_type"), paa);
auto* aapaa = ty.alias("aapaa_type", apaa); auto* aapaa = create<Alias>(Sym("aapaa_type"), apaa);
Pointer paapaa{aapaa, ast::StorageClass::kUniform}; auto* paapaa = create<Pointer>(aapaa, ast::StorageClass::kUniform);
auto* apaapaa = ty.alias("apaapaa_type", &paapaa); auto* apaapaa = create<Alias>(Sym("apaapaa_type"), paapaa);
EXPECT_EQ(apaapaa->UnwrapAll(), &paa); EXPECT_EQ(apaapaa->UnwrapAll(), paa);
} }
TEST_F(AliasTest, UnwrapAll_AccessControlPointer) { TEST_F(AliasTest, UnwrapAll_AccessControlPointer) {
AccessControl a{ast::AccessControl::kReadOnly, ty.u32()}; auto* a = create<AccessControl>(ast::AccessControl::kReadOnly, ty.u32());
Pointer pa{&a, ast::StorageClass::kUniform}; auto* pa = create<Pointer>(a, ast::StorageClass::kUniform);
EXPECT_EQ(pa.type(), &a); EXPECT_EQ(pa->type(), a);
EXPECT_EQ(pa.UnwrapAll(), ty.u32()); EXPECT_EQ(pa->UnwrapAll(), ty.u32());
} }
TEST_F(AliasTest, UnwrapAll_PointerAccessControl) { TEST_F(AliasTest, UnwrapAll_PointerAccessControl) {
Pointer p{ty.u32(), ast::StorageClass::kUniform}; auto* p = create<Pointer>(ty.u32(), ast::StorageClass::kUniform);
AccessControl a{ast::AccessControl::kReadOnly, &p}; auto* a = create<AccessControl>(ast::AccessControl::kReadOnly, p);
EXPECT_EQ(a.type(), &p); EXPECT_EQ(a->type(), p);
EXPECT_EQ(a.UnwrapAll(), ty.u32()); EXPECT_EQ(a->UnwrapAll(), ty.u32());
} }
TEST_F(AliasTest, UnwrapAliasIfNeeded) { TEST_F(AliasTest, UnwrapAliasIfNeeded) {
auto* alias1 = ty.alias("alias1", ty.f32()); auto* alias1 = create<Alias>(Sym("alias1"), ty.f32());
auto* alias2 = ty.alias("alias2", alias1); auto* alias2 = create<Alias>(Sym("alias2"), alias1);
auto* alias3 = ty.alias("alias3", alias2); auto* alias3 = create<Alias>(Sym("alias3"), alias2);
EXPECT_EQ(alias3->UnwrapAliasIfNeeded(), ty.f32()); EXPECT_EQ(alias3->UnwrapAliasIfNeeded(), ty.f32());
} }

View File

@ -27,7 +27,7 @@ TEST_F(StructTypeTest, Creation) {
auto* impl = auto* impl =
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{}); create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
auto* ptr = impl; auto* ptr = impl;
auto* s = ty.struct_(impl); auto s = ty.struct_(impl);
EXPECT_EQ(s->impl(), ptr); EXPECT_EQ(s->impl(), ptr);
} }
@ -35,7 +35,7 @@ TEST_F(StructTypeTest, Is) {
auto name = Sym("S"); auto name = Sym("S");
auto* impl = auto* impl =
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{}); create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
auto* s = ty.struct_(impl); auto s = ty.struct_(impl);
sem::Type* ty = s; sem::Type* ty = s;
EXPECT_FALSE(ty->Is<AccessControl>()); EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>()); EXPECT_FALSE(ty->Is<Alias>());
@ -56,7 +56,7 @@ TEST_F(StructTypeTest, TypeName) {
auto name = Sym("my_struct"); auto name = Sym("my_struct");
auto* impl = auto* impl =
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{}); create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
auto* s = ty.struct_(impl); auto s = ty.struct_(impl);
EXPECT_EQ(s->type_name(), "__struct_$1"); EXPECT_EQ(s->type_name(), "__struct_$1");
} }
@ -64,7 +64,7 @@ TEST_F(StructTypeTest, FriendlyName) {
auto name = Sym("my_struct"); auto name = Sym("my_struct");
auto* impl = auto* impl =
create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{}); create<ast::Struct>(name, ast::StructMemberList{}, ast::DecorationList{});
auto* s = ty.struct_(impl); auto s = ty.struct_(impl);
EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct"); EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
} }

View File

@ -136,7 +136,7 @@ Output FirstIndexOffset::Run(const Program* in, const DataMap& data) {
instance_index_offset = offset; instance_index_offset = offset;
offset += 4; offset += 4;
} }
auto* struct_type = auto struct_type =
ctx.dst->Structure(ctx.dst->Symbols().New(), std::move(members), ctx.dst->Structure(ctx.dst->Symbols().New(), std::move(members),
{ctx.dst->create<ast::StructBlockDecoration>()}); {ctx.dst->create<ast::StructBlockDecoration>()});

View File

@ -198,7 +198,7 @@ struct State {
// Creating the struct type // Creating the struct type
static const char kStructName[] = "TintVertexData"; static const char kStructName[] = "TintVertexData";
auto* struct_type = ctx.dst->Structure( auto struct_type = ctx.dst->Structure(
ctx.dst->Symbols().New(kStructName), ctx.dst->Symbols().New(kStructName),
{ {
ctx.dst->Member(GetStructBufferName(), ctx.dst->Member(GetStructBufferName(),
@ -207,7 +207,7 @@ struct State {
{ {
ctx.dst->create<ast::StructBlockDecoration>(), ctx.dst->create<ast::StructBlockDecoration>(),
}); });
auto* access = auto access =
ctx.dst->ty.access(ast::AccessControl::kReadOnly, struct_type); ctx.dst->ty.access(ast::AccessControl::kReadOnly, struct_type);
for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) { for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
// The decorated variable with struct type // The decorated variable with struct type

View File

@ -22,22 +22,40 @@
namespace tint { namespace tint {
namespace ast { namespace ast {
class AccessControl;
class Alias;
class Array; class Array;
class Bool; class Bool;
class DepthTexture;
class F32; class F32;
class I32; class I32;
class Matrix; class Matrix;
class MultisampledTexture;
class Pointer;
class Sampler;
class SampledTexture;
class StorageTexture;
class Struct;
class U32; class U32;
class Vector; class Vector;
class Void; class Void;
} // namespace ast } // namespace ast
namespace sem { namespace sem {
class AccessControl;
class Alias;
class ArrayType; class ArrayType;
class Bool; class Bool;
class DepthTexture;
class F32; class F32;
class I32; class I32;
class Matrix; class Matrix;
class MultisampledTexture;
class Pointer;
class Sampler;
class SampledTexture;
class StorageTexture;
class StructType;
class U32; class U32;
class Vector; class Vector;
class Void; class Void;
@ -59,9 +77,9 @@ namespace typ { // type-pair
template <typename AST, typename SEM> template <typename AST, typename SEM>
struct TypePair { struct TypePair {
/// The ast::Type pointer /// The ast::Type pointer
AST const* const ast = nullptr; AST const* ast = nullptr;
/// The sem::Type pointer /// The sem::Type pointer
SEM const* const sem = nullptr; SEM const* sem = nullptr;
/// Constructor /// Constructor
TypePair() = default; TypePair() = default;
@ -89,15 +107,42 @@ struct TypePair {
operator SEM*() const { return const_cast<SEM*>(sem); } operator SEM*() const { return const_cast<SEM*>(sem); }
/// @returns the sem::Type pointer /// @returns the sem::Type pointer
SEM* operator->() const { return const_cast<SEM*>(sem); } SEM* operator->() const { return const_cast<SEM*>(sem); }
/// @param ty the semantic type to compare against
/// @returns true if the semantic type is equal to `ty`
bool operator==(sem::Type* ty) const { return sem == ty; }
/// @param other the TypePair to compare against
/// @returns true if this TypePair is less than `other`
template <typename OTHER_AST, typename OTHER_SEM>
bool operator<(const TypePair<OTHER_AST, OTHER_SEM>& other) const {
if (sem < other.sem) {
return true;
}
if (sem > other.sem) {
return false;
}
return ast < other.ast;
}
}; };
using Type = TypePair<ast::Type, sem::Type>; using Type = TypePair<ast::Type, sem::Type>;
using AccessControl = TypePair<ast::AccessControl, sem::AccessControl>;
using Alias = TypePair<ast::Alias, sem::Alias>;
using Array = TypePair<ast::Array, sem::ArrayType>; using Array = TypePair<ast::Array, sem::ArrayType>;
using Bool = TypePair<ast::Bool, sem::Bool>; using Bool = TypePair<ast::Bool, sem::Bool>;
using DepthTexture = TypePair<ast::DepthTexture, sem::DepthTexture>;
using F32 = TypePair<ast::F32, sem::F32>; using F32 = TypePair<ast::F32, sem::F32>;
using I32 = TypePair<ast::I32, sem::I32>; using I32 = TypePair<ast::I32, sem::I32>;
using Matrix = TypePair<ast::Matrix, sem::Matrix>; using Matrix = TypePair<ast::Matrix, sem::Matrix>;
using MultisampledTexture =
TypePair<ast::MultisampledTexture, sem::MultisampledTexture>;
using Pointer = TypePair<ast::Pointer, sem::Pointer>;
using Sampler = TypePair<ast::Sampler, sem::Sampler>;
using SampledTexture = TypePair<ast::SampledTexture, sem::SampledTexture>;
using StorageTexture = TypePair<ast::StorageTexture, sem::StorageTexture>;
using Struct = TypePair<ast::Struct, sem::StructType>;
using U32 = TypePair<ast::U32, sem::U32>; using U32 = TypePair<ast::U32, sem::U32>;
using Vector = TypePair<ast::Vector, sem::Vector>; using Vector = TypePair<ast::Vector, sem::Vector>;
using Void = TypePair<ast::Void, sem::Void>; using Void = TypePair<ast::Void, sem::Void>;

View File

@ -25,7 +25,7 @@ using ::testing::HasSubstr;
using HlslGeneratorImplTest_Alias = TestHelper; using HlslGeneratorImplTest_Alias = TestHelper;
TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_F32) { TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_F32) {
auto* alias = ty.alias("a", ty.f32()); auto alias = ty.alias("a", ty.f32());
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -45,11 +45,11 @@ TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_NameCollision) {
} }
TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_Struct) { TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_Struct) {
auto* s = Structure("A", { auto s = Structure("A", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.i32()), Member("b", ty.i32()),
}); });
auto* alias = ty.alias("B", s); auto alias = ty.alias("B", s);
AST().AddConstructedType(alias); AST().AddConstructedType(alias);
Global("g", alias, ast::StorageClass::kPrivate); Global("g", alias, ast::StorageClass::kPrivate);

View File

@ -195,7 +195,7 @@ TEST_F(HlslGeneratorImplTest_Constructor,
} }
TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct) { TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct) {
auto* str = Structure("S", { auto str = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
Member("c", ty.vec3<i32>()), Member("c", ty.vec3<i32>()),
@ -212,7 +212,7 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct) {
} }
TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct_Empty) { TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct_Empty) {
auto* str = Structure("S", { auto str = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
Member("c", ty.vec3<i32>()), Member("c", ty.vec3<i32>()),

View File

@ -179,7 +179,7 @@ TEST_F(HlslGeneratorImplTest_Function,
// const g = inputs.col2; // const g = inputs.col2;
// const p = inputs.pos; // const p = inputs.pos;
// } // }
auto* interface_struct = Structure( auto interface_struct = Structure(
"Interface", "Interface",
{ {
Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)}), Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)}),
@ -252,7 +252,7 @@ TEST_F(HlslGeneratorImplTest_Function,
// fn vert_main2() -> VertexOutput { // fn vert_main2() -> VertexOutput {
// return foo(0.25); // return foo(0.25);
// } // }
auto* vertex_output_struct = Structure( auto vertex_output_struct = Structure(
"VertexOutput", "VertexOutput",
{Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)})}); {Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)})});
@ -307,7 +307,7 @@ tint_symbol_2 vert_main2() {
TEST_F(HlslGeneratorImplTest_Function, TEST_F(HlslGeneratorImplTest_Function,
Emit_Decoration_EntryPoint_With_Uniform) { Emit_Decoration_EntryPoint_With_Uniform) {
auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())}, auto ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ubo = Global( auto* ubo = Global(
"ubo", ubo_ty, ast::StorageClass::kUniform, nullptr, "ubo", ubo_ty, ast::StorageClass::kUniform, nullptr,
@ -359,7 +359,7 @@ void frag_main() {
TEST_F(HlslGeneratorImplTest_Function, TEST_F(HlslGeneratorImplTest_Function,
Emit_Decoration_EntryPoint_With_UniformStruct) { Emit_Decoration_EntryPoint_With_UniformStruct) {
auto* s = Structure("Uniforms", {Member("coord", ty.vec4<f32>())}, auto s = Structure("Uniforms", {Member("coord", ty.vec4<f32>())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
Global("uniforms", s, ast::StorageClass::kUniform, nullptr, Global("uniforms", s, ast::StorageClass::kUniform, nullptr,
@ -401,7 +401,7 @@ void frag_main() {
TEST_F(HlslGeneratorImplTest_Function, TEST_F(HlslGeneratorImplTest_Function,
Emit_Decoration_EntryPoint_With_RW_StorageBuffer_Read) { Emit_Decoration_EntryPoint_With_RW_StorageBuffer_Read) {
auto* s = Structure("Data", auto s = Structure("Data",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -447,7 +447,7 @@ void frag_main() {
TEST_F(HlslGeneratorImplTest_Function, TEST_F(HlslGeneratorImplTest_Function,
Emit_Decoration_EntryPoint_With_RO_StorageBuffer_Read) { Emit_Decoration_EntryPoint_With_RO_StorageBuffer_Read) {
auto* s = Structure("Data", auto s = Structure("Data",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -493,7 +493,7 @@ void frag_main() {
TEST_F(HlslGeneratorImplTest_Function, TEST_F(HlslGeneratorImplTest_Function,
Emit_Decoration_EntryPoint_With_WO_StorageBuffer_Store) { Emit_Decoration_EntryPoint_With_WO_StorageBuffer_Store) {
auto* s = Structure("Data", auto s = Structure("Data",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -536,7 +536,7 @@ void frag_main() {
TEST_F(HlslGeneratorImplTest_Function, TEST_F(HlslGeneratorImplTest_Function,
Emit_Decoration_EntryPoint_With_StorageBuffer_Store) { Emit_Decoration_EntryPoint_With_StorageBuffer_Store) {
auto* s = Structure("Data", auto s = Structure("Data",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -742,7 +742,7 @@ ep_1_out ep_1(ep_1_in tint_in) {
TEST_F(HlslGeneratorImplTest_Function, TEST_F(HlslGeneratorImplTest_Function,
Emit_Decoration_Called_By_EntryPoint_With_Uniform) { Emit_Decoration_Called_By_EntryPoint_With_Uniform) {
auto* s = Structure("S", {Member("x", ty.f32())}, auto s = Structure("S", {Member("x", ty.f32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
Global("coord", s, ast::StorageClass::kUniform, nullptr, Global("coord", s, ast::StorageClass::kUniform, nullptr,
{ {
@ -792,9 +792,9 @@ void frag_main() {
TEST_F(HlslGeneratorImplTest_Function, TEST_F(HlslGeneratorImplTest_Function,
Emit_Decoration_Called_By_EntryPoint_With_StorageBuffer) { Emit_Decoration_Called_By_EntryPoint_With_StorageBuffer) {
auto* s = Structure("S", {Member("x", ty.f32())}, auto s = Structure("S", {Member("x", ty.f32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kReadWrite, s); auto ac = ty.access(ast::AccessControl::kReadWrite, s);
Global("coord", ac, ast::StorageClass::kStorage, nullptr, Global("coord", ac, ast::StorageClass::kStorage, nullptr,
{ {
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
@ -981,7 +981,7 @@ TEST_F(HlslGeneratorImplTest_Function,
// return; // return;
// } // }
auto* s = Structure("Data", {Member("d", ty.f32())}, auto s = Structure("Data", {Member("d", ty.f32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
sem::AccessControl ac(ast::AccessControl::kReadWrite, s); sem::AccessControl ac(ast::AccessControl::kReadWrite, s);

View File

@ -96,11 +96,10 @@ class HlslGeneratorImplTest_MemberAccessorBase : public BASE {
void SetupStorageBuffer(ast::StructMemberList members) { void SetupStorageBuffer(ast::StructMemberList members) {
ProgramBuilder& b = *this; ProgramBuilder& b = *this;
auto* s = auto s =
b.Structure("Data", members, {b.create<ast::StructBlockDecoration>()}); b.Structure("Data", members, {b.create<ast::StructBlockDecoration>()});
auto* ac_ty = auto ac_ty = b.ty.access(ast::AccessControl::kReadWrite, s);
b.create<sem::AccessControl>(ast::AccessControl::kReadWrite, s);
b.Global("data", ac_ty, ast::StorageClass::kStorage, nullptr, b.Global("data", ac_ty, ast::StorageClass::kStorage, nullptr,
ast::DecorationList{ ast::DecorationList{
@ -126,7 +125,7 @@ using HlslGeneratorImplTest_MemberAccessorWithParam =
HlslGeneratorImplTest_MemberAccessorBase<TestParamHelper<T>>; HlslGeneratorImplTest_MemberAccessorBase<TestParamHelper<T>>;
TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) { TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
auto* s = Structure("Data", {Member("mem", ty.f32())}); auto s = Structure("Data", {Member("mem", ty.f32())});
Global("str", s, ast::StorageClass::kPrivate); Global("str", s, ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem"); auto* expr = MemberAccessor("str", "mem");
@ -520,7 +519,7 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Load_MultiLevel) {
// var<storage> data : Pre; // var<storage> data : Pre;
// data.c[2].b // data.c[2].b
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.vec3<f32>()), Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}); });
@ -566,7 +565,7 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
// var<storage> data : Pre; // var<storage> data : Pre;
// data.c[2].b.xy // data.c[2].b.xy
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.vec3<f32>()), Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}); });
@ -614,7 +613,7 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
// var<storage> data : Pre; // var<storage> data : Pre;
// data.c[2].b.g // data.c[2].b.g
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.vec3<f32>()), Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}); });
@ -662,7 +661,7 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
// var<storage> data : Pre; // var<storage> data : Pre;
// data.c[2].b[1] // data.c[2].b[1]
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.vec3<f32>()), Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}); });
@ -709,7 +708,7 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, StorageBuffer_Store_MultiLevel) {
// var<storage> data : Pre; // var<storage> data : Pre;
// data.c[2].b = vec3<f32>(1.f, 2.f, 3.f); // data.c[2].b = vec3<f32>(1.f, 2.f, 3.f);
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.vec3<f32>()), Member("a", ty.vec3<f32>()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}); });
@ -754,7 +753,7 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
// var<storage> data : Pre; // var<storage> data : Pre;
// data.c[2].b.y = 1.f; // data.c[2].b.y = 1.f;
auto* inner = Structure("Inner", { auto inner = Structure("Inner", {
Member("a", ty.vec3<i32>()), Member("a", ty.vec3<i32>()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}); });

View File

@ -26,7 +26,7 @@ namespace {
using HlslSanitizerTest = TestHelper; using HlslSanitizerTest = TestHelper;
TEST_F(HlslSanitizerTest, ArrayLength) { TEST_F(HlslSanitizerTest, ArrayLength) {
auto* sb_ty = Structure("SB", auto sb_ty = Structure("SB",
{ {
Member("x", ty.f32()), Member("x", ty.f32()),
Member("arr", ty.array(ty.vec4<f32>())), Member("arr", ty.array(ty.vec4<f32>())),
@ -34,8 +34,7 @@ TEST_F(HlslSanitizerTest, ArrayLength) {
{ {
create<ast::StructBlockDecoration>(), create<ast::StructBlockDecoration>(),
}); });
auto* ac_ty = auto ac_ty = ty.access(ast::AccessControl::kReadOnly, sb_ty);
create<sem::AccessControl>(ast::AccessControl::kReadOnly, sb_ty);
Global("sb", ac_ty, ast::StorageClass::kStorage, nullptr, Global("sb", ac_ty, ast::StorageClass::kStorage, nullptr,
ast::DecorationList{ ast::DecorationList{
@ -101,7 +100,7 @@ TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) {
} }
TEST_F(HlslSanitizerTest, PromoteStructInitializerToConstVar) { TEST_F(HlslSanitizerTest, PromoteStructInitializerToConstVar) {
auto* str = Structure("S", { auto str = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
Member("c", ty.i32()), Member("c", ty.i32()),

View File

@ -33,7 +33,7 @@ using ::testing::HasSubstr;
using HlslGeneratorImplTest_Type = TestHelper; using HlslGeneratorImplTest_Type = TestHelper;
TEST_F(HlslGeneratorImplTest_Type, EmitType_Alias) { TEST_F(HlslGeneratorImplTest_Type, EmitType_Alias) {
auto* alias = ty.alias("alias", ty.f32()); auto alias = ty.alias("alias", ty.f32());
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -156,7 +156,7 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Pointer) {
} }
TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) { TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
@ -173,7 +173,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) {
} }
TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl_OmittedIfStorageBuffer) { TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl_OmittedIfStorageBuffer) {
auto* s = Structure("S", auto s = Structure("S",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -189,7 +189,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl_OmittedIfStorageBuffer) {
} }
TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) { TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
@ -205,7 +205,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) {
/// TODO(bclayton): Enable this, fix it, add tests for vector, matrix, array and /// TODO(bclayton): Enable this, fix it, add tests for vector, matrix, array and
/// nested structures. /// nested structures.
TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_InjectPadding) { TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_InjectPadding) {
auto* s = Structure( auto s = Structure(
"S", { "S", {
Member("a", ty.i32(), {MemberSize(32)}), Member("a", ty.i32(), {MemberSize(32)}),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -229,7 +229,7 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_InjectPadding) {
} }
TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) { TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("double", ty.i32()), Member("double", ty.i32()),
Member("float", ty.f32()), Member("float", ty.f32()),
}); });
@ -247,7 +247,7 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) {
// TODO(dsinclair): How to translate [[block]] // TODO(dsinclair): How to translate [[block]]
TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_WithDecoration) { TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_WithDecoration) {
auto* s = Structure("S", auto s = Structure("S",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -326,7 +326,7 @@ using HlslDepthTexturesTest = TestParamHelper<HlslDepthTextureData>;
TEST_P(HlslDepthTexturesTest, Emit) { TEST_P(HlslDepthTexturesTest, Emit) {
auto params = GetParam(); auto params = GetParam();
auto* t = create<sem::DepthTexture>(params.dim); auto t = ty.depth_texture(params.dim);
Global("tex", t, ast::StorageClass::kUniformConstant, nullptr, Global("tex", t, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
@ -373,7 +373,7 @@ using HlslSampledTexturesTest = TestParamHelper<HlslSampledTextureData>;
TEST_P(HlslSampledTexturesTest, Emit) { TEST_P(HlslSampledTexturesTest, Emit) {
auto params = GetParam(); auto params = GetParam();
sem::Type* datatype = nullptr; typ::Type datatype;
switch (params.datatype) { switch (params.datatype) {
case TextureDataType::F32: case TextureDataType::F32:
datatype = ty.f32(); datatype = ty.f32();
@ -385,7 +385,7 @@ TEST_P(HlslSampledTexturesTest, Emit) {
datatype = ty.i32(); datatype = ty.i32();
break; break;
} }
auto* t = create<sem::SampledTexture>(params.dim, datatype); auto t = ty.sampled_texture(params.dim, datatype);
Global("tex", t, ast::StorageClass::kUniformConstant, nullptr, Global("tex", t, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
@ -524,10 +524,8 @@ using HlslStorageTexturesTest = TestParamHelper<HlslStorageTextureData>;
TEST_P(HlslStorageTexturesTest, Emit) { TEST_P(HlslStorageTexturesTest, Emit) {
auto params = GetParam(); auto params = GetParam();
auto* subtype = sem::StorageTexture::SubtypeFor(params.imgfmt, Types()); auto t = ty.storage_texture(params.dim, params.imgfmt);
auto* t = create<sem::StorageTexture>(params.dim, params.imgfmt, subtype); auto ac = ty.access(params.ro ? ast::AccessControl::kReadOnly
auto* ac =
create<sem::AccessControl>(params.ro ? ast::AccessControl::kReadOnly
: ast::AccessControl::kWriteOnly, : ast::AccessControl::kWriteOnly,
t); t);

View File

@ -39,7 +39,7 @@ TEST_F(HlslGeneratorImplTest_WorkgroupVar, Basic) {
} }
TEST_F(HlslGeneratorImplTest_WorkgroupVar, Aliased) { TEST_F(HlslGeneratorImplTest_WorkgroupVar, Aliased) {
auto* alias = ty.alias("F32", ty.f32()); auto alias = ty.alias("F32", ty.f32());
AST().AddConstructedType(alias); AST().AddConstructedType(alias);
Global("wg", alias, ast::StorageClass::kWorkgroup); Global("wg", alias, ast::StorageClass::kWorkgroup);

View File

@ -22,7 +22,7 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitConstructedType_F32) { TEST_F(MslGeneratorImplTest, EmitConstructedType_F32) {
auto* alias = ty.alias("a", ty.f32()); auto alias = ty.alias("a", ty.f32());
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -32,7 +32,7 @@ TEST_F(MslGeneratorImplTest, EmitConstructedType_F32) {
} }
TEST_F(MslGeneratorImplTest, EmitConstructedType_Struct) { TEST_F(MslGeneratorImplTest, EmitConstructedType_Struct) {
auto* s = Structure("a", { auto s = Structure("a", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.i32()), Member("b", ty.i32()),
}); });
@ -48,12 +48,12 @@ TEST_F(MslGeneratorImplTest, EmitConstructedType_Struct) {
} }
TEST_F(MslGeneratorImplTest, EmitConstructedType_AliasStructIdent) { TEST_F(MslGeneratorImplTest, EmitConstructedType_AliasStructIdent) {
auto* s = Structure("b", { auto s = Structure("b", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.i32()), Member("b", ty.i32()),
}); });
auto* alias = ty.alias("a", s); auto alias = ty.alias("a", s);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -145,7 +145,7 @@ TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Array) {
} }
TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Struct) { TEST_F(MslGeneratorImplTest, EmitConstructor_Type_Struct) {
auto* str = Structure("S", { auto str = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
Member("c", ty.vec3<i32>()), Member("c", ty.vec3<i32>()),

View File

@ -170,7 +170,7 @@ TEST_F(MslGeneratorImplTest,
// const r = colors.col1; // const r = colors.col1;
// const g = colors.col2; // const g = colors.col2;
// } // }
auto* interface_struct = Structure( auto interface_struct = Structure(
"Interface", "Interface",
{ {
Member("col1", ty.f32(), {Location(1)}), Member("col1", ty.f32(), {Location(1)}),
@ -245,7 +245,7 @@ TEST_F(MslGeneratorImplTest,
// fn vert_main2() -> VertexOutput { // fn vert_main2() -> VertexOutput {
// return foo(0.25); // return foo(0.25);
// } // }
auto* vertex_output_struct = Structure( auto vertex_output_struct = Structure(
"VertexOutput", "VertexOutput",
{Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)})}); {Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)})});
@ -300,7 +300,7 @@ vertex tint_symbol_2 vert_main2() {
TEST_F(MslGeneratorImplTest, TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_EntryPoint_With_RW_StorageBuffer) { Emit_FunctionDecoration_EntryPoint_With_RW_StorageBuffer) {
auto* s = Structure("Data", auto s = Structure("Data",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -345,7 +345,7 @@ fragment void frag_main(device Data& coord [[buffer(0)]]) {
TEST_F(MslGeneratorImplTest, TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_EntryPoint_With_RO_StorageBuffer) { Emit_FunctionDecoration_EntryPoint_With_RO_StorageBuffer) {
auto* s = Structure("Data", auto s = Structure("Data",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -550,7 +550,7 @@ fragment ep_1_out ep_1(float4 coord [[position]]) {
TEST_F(MslGeneratorImplTest, TEST_F(MslGeneratorImplTest,
Emit_Decoration_Called_By_EntryPoint_With_Uniform) { Emit_Decoration_Called_By_EntryPoint_With_Uniform) {
auto* ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())}, auto ubo_ty = Structure("UBO", {Member("coord", ty.vec4<f32>())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ubo = Global( auto* ubo = Global(
"ubo", ubo_ty, ast::StorageClass::kUniform, nullptr, "ubo", ubo_ty, ast::StorageClass::kUniform, nullptr,
@ -601,7 +601,7 @@ fragment void frag_main(constant UBO& ubo [[buffer(0)]]) {
TEST_F(MslGeneratorImplTest, TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_Called_By_EntryPoint_With_RW_StorageBuffer) { Emit_FunctionDecoration_Called_By_EntryPoint_With_RW_StorageBuffer) {
auto* s = Structure("Data", auto s = Structure("Data",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -657,7 +657,7 @@ fragment void frag_main(device Data& coord [[buffer(0)]]) {
TEST_F(MslGeneratorImplTest, TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_Called_By_EntryPoint_With_RO_StorageBuffer) { Emit_FunctionDecoration_Called_By_EntryPoint_With_RO_StorageBuffer) {
auto* s = Structure("Data", auto s = Structure("Data",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -796,7 +796,7 @@ TEST_F(MslGeneratorImplTest,
// return; // return;
// } // }
auto* s = Structure("Data", {Member("d", ty.f32())}, auto s = Structure("Data", {Member("d", ty.f32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
sem::AccessControl ac(ast::AccessControl::kReadWrite, s); sem::AccessControl ac(ast::AccessControl::kReadWrite, s);

View File

@ -58,7 +58,7 @@ using uint = unsigned int;
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitType_Alias) { TEST_F(MslGeneratorImplTest, EmitType_Alias) {
auto* alias = ty.alias("alias", ty.f32()); auto alias = ty.alias("alias", ty.f32());
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -173,7 +173,7 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Pointer) {
} }
TEST_F(MslGeneratorImplTest, EmitType_Struct) { TEST_F(MslGeneratorImplTest, EmitType_Struct) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
@ -185,7 +185,7 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct) {
} }
TEST_F(MslGeneratorImplTest, EmitType_StructDecl) { TEST_F(MslGeneratorImplTest, EmitType_StructDecl) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
@ -201,7 +201,7 @@ TEST_F(MslGeneratorImplTest, EmitType_StructDecl) {
} }
TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_NonComposites) { TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_NonComposites) {
auto* s = auto s =
Structure("S", Structure("S",
{ {
Member("a", ty.i32(), {MemberSize(32)}), Member("a", ty.i32(), {MemberSize(32)}),
@ -315,20 +315,20 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_NonComposites) {
TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_Structures) { TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_Structures) {
// inner_x: size(1024), align(512) // inner_x: size(1024), align(512)
auto* inner_x = auto inner_x =
Structure("inner_x", { Structure("inner_x", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32(), {MemberAlign(512)}), Member("b", ty.f32(), {MemberAlign(512)}),
}); });
// inner_y: size(516), align(4) // inner_y: size(516), align(4)
auto* inner_y = auto inner_y =
Structure("inner_y", { Structure("inner_y", {
Member("a", ty.i32(), {MemberSize(512)}), Member("a", ty.i32(), {MemberSize(512)}),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
auto* s = Structure("S", auto s = Structure("S",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", inner_x), Member("b", inner_x),
@ -401,8 +401,7 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_Structures) {
TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) { TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) {
// inner: size(1024), align(512) // inner: size(1024), align(512)
auto* inner = auto inner = Structure("inner", {
Structure("inner", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32(), {MemberAlign(512)}), Member("b", ty.f32(), {MemberAlign(512)}),
}); });
@ -416,8 +415,7 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) {
// array_z: size(4), align(4) // array_z: size(4), align(4)
auto array_z = ty.array<f32>(); auto array_z = ty.array<f32>();
auto* s = auto s = Structure("S",
Structure("S",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", array_x), Member("b", array_x),
@ -497,7 +495,7 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) {
} }
TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) { TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) {
auto* s = Structure( auto s = Structure(
"S", "S",
{ {
// uses symbols tint_pad_[0..9] and tint_pad_[20..35] // uses symbols tint_pad_[0..9] and tint_pad_[20..35]
@ -584,7 +582,7 @@ TEST_F(MslGeneratorImplTest, AttemptTintPadSymbolCollision) {
// TODO(dsinclair): How to translate [[block]] // TODO(dsinclair): How to translate [[block]]
TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) { TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) {
auto* s = Structure("S", auto s = Structure("S",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
@ -631,20 +629,20 @@ TEST_F(MslGeneratorImplTest, EmitType_Void) {
} }
TEST_F(MslGeneratorImplTest, EmitType_Sampler) { TEST_F(MslGeneratorImplTest, EmitType_Sampler) {
sem::Sampler sampler(ast::SamplerKind::kSampler); auto sampler = ty.sampler(ast::SamplerKind::kSampler);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&sampler, "")) << gen.error(); ASSERT_TRUE(gen.EmitType(sampler, "")) << gen.error();
EXPECT_EQ(gen.result(), "sampler"); EXPECT_EQ(gen.result(), "sampler");
} }
TEST_F(MslGeneratorImplTest, EmitType_SamplerComparison) { TEST_F(MslGeneratorImplTest, EmitType_SamplerComparison) {
sem::Sampler sampler(ast::SamplerKind::kComparisonSampler); auto sampler = ty.sampler(ast::SamplerKind::kComparisonSampler);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(&sampler, "")) << gen.error(); ASSERT_TRUE(gen.EmitType(sampler, "")) << gen.error();
EXPECT_EQ(gen.result(), "sampler"); EXPECT_EQ(gen.result(), "sampler");
} }
@ -738,12 +736,8 @@ using MslStorageTexturesTest = TestParamHelper<MslStorageTextureData>;
TEST_P(MslStorageTexturesTest, Emit) { TEST_P(MslStorageTexturesTest, Emit) {
auto params = GetParam(); auto params = GetParam();
auto* subtype = auto s = ty.storage_texture(params.dim, ast::ImageFormat::kR32Float);
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()); auto ac = ty.access(params.ro ? ast::AccessControl::kReadOnly
auto* s = create<sem::StorageTexture>(params.dim, ast::ImageFormat::kR32Float,
subtype);
auto* ac =
create<sem::AccessControl>(params.ro ? ast::AccessControl::kReadOnly
: ast::AccessControl::kWriteOnly, : ast::AccessControl::kWriteOnly,
s); s);
Global("test_var", ac, ast::StorageClass::kInput); Global("test_var", ac, ast::StorageClass::kInput);

View File

@ -67,7 +67,7 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Array) {
} }
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) { TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });

View File

@ -219,7 +219,7 @@ TEST_F(BuilderTest, MemberAccessor) {
// var ident : my_struct // var ident : my_struct
// ident.b // ident.b
auto* s = Structure("my_struct", { auto s = Structure("my_struct", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
@ -263,12 +263,12 @@ TEST_F(BuilderTest, MemberAccessor_Nested) {
// //
// var ident : my_struct // var ident : my_struct
// ident.inner.a // ident.inner.a
auto* inner_struct = Structure("Inner", { auto inner_struct = Structure("Inner", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
auto* s_type = Structure("my_struct", {Member("inner", inner_struct)}); auto s_type = Structure("my_struct", {Member("inner", inner_struct)});
auto* var = Global("ident", s_type, ast::StorageClass::kFunction); auto* var = Global("ident", s_type, ast::StorageClass::kFunction);
auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "b"); auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "b");
@ -307,7 +307,7 @@ TEST_F(BuilderTest, MemberAccessor_NonPointer) {
// let ident : my_struct = my_struct(); // let ident : my_struct = my_struct();
// ident.b // ident.b
auto* s = Structure("my_struct", { auto s = Structure("my_struct", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
@ -345,12 +345,12 @@ TEST_F(BuilderTest, MemberAccessor_Nested_NonPointer) {
// //
// let ident : my_struct = my_struct(); // let ident : my_struct = my_struct();
// ident.inner.a // ident.inner.a
auto* inner_struct = Structure("Inner", { auto inner_struct = Structure("Inner", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
auto* s_type = Structure("my_struct", {Member("inner", inner_struct)}); auto s_type = Structure("my_struct", {Member("inner", inner_struct)});
auto* var = GlobalConst("ident", s_type, auto* var = GlobalConst("ident", s_type,
Construct(s_type, Construct(inner_struct, 0.f, 0.f))); Construct(s_type, Construct(inner_struct, 0.f, 0.f)));
@ -388,13 +388,13 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
// //
// var ident : my_struct // var ident : my_struct
// ident.inner.a // ident.inner.a
auto* inner_struct = Structure("Inner", { auto inner_struct = Structure("Inner", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
auto* alias = ty.alias("Inner", inner_struct); auto alias = ty.alias("Inner", inner_struct);
auto* s_type = Structure("Outer", {Member("inner", alias)}); auto s_type = Structure("Outer", {Member("inner", alias)});
auto* var = Global("ident", s_type, ast::StorageClass::kFunction); auto* var = Global("ident", s_type, ast::StorageClass::kFunction);
auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a"); auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a");
@ -434,12 +434,12 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) {
// //
// var ident : my_struct // var ident : my_struct
// ident.inner.a = 2.0f; // ident.inner.a = 2.0f;
auto* inner_struct = Structure("Inner", { auto inner_struct = Structure("Inner", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
auto* s_type = Structure("my_struct", {Member("inner", inner_struct)}); auto s_type = Structure("my_struct", {Member("inner", inner_struct)});
auto* var = Global("ident", s_type, ast::StorageClass::kFunction); auto* var = Global("ident", s_type, ast::StorageClass::kFunction);
auto* expr = auto* expr =
@ -483,12 +483,12 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) {
// var ident : my_struct // var ident : my_struct
// var store : f32 = ident.inner.a // var store : f32 = ident.inner.a
auto* inner_struct = Structure("Inner", { auto inner_struct = Structure("Inner", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
auto* s_type = Structure("my_struct", {Member("inner", inner_struct)}); auto s_type = Structure("my_struct", {Member("inner", inner_struct)});
auto* var = Global("ident", s_type, ast::StorageClass::kFunction); auto* var = Global("ident", s_type, ast::StorageClass::kFunction);
auto* store = Global("store", ty.f32(), ast::StorageClass::kFunction); auto* store = Global("store", ty.f32(), ast::StorageClass::kFunction);
@ -693,11 +693,11 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
// var index : array<A, 2> // var index : array<A, 2>
// index[0].foo[2].bar.baz.yx // index[0].foo[2].bar.baz.yx
auto* c_type = Structure("C", {Member("baz", ty.vec3<f32>())}); auto c_type = Structure("C", {Member("baz", ty.vec3<f32>())});
auto* b_type = Structure("B", {Member("bar", c_type)}); auto b_type = Structure("B", {Member("bar", c_type)});
auto b_ary_type = ty.array(b_type, 3); auto b_ary_type = ty.array(b_type, 3);
auto* a_type = Structure("A", {Member("foo", b_ary_type)}); auto a_type = Structure("A", {Member("foo", b_ary_type)});
auto a_ary_type = ty.array(a_type, 2); auto a_ary_type = ty.array(a_type, 2);
auto* var = Global("index", a_ary_type, ast::StorageClass::kFunction); auto* var = Global("index", a_ary_type, ast::StorageClass::kFunction);

View File

@ -176,7 +176,7 @@ TEST_F(BuilderTest, Assign_StructMember) {
// var ident : my_struct // var ident : my_struct
// ident.b = 4.0; // ident.b = 4.0;
auto* s = Structure("my_struct", { auto s = Structure("my_struct", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });

View File

@ -93,7 +93,7 @@ TEST_F(SpvBuilderConstructorTest, Type_WithAlias) {
// type Int = i32 // type Int = i32
// cast<Int>(2.3f) // cast<Int>(2.3f)
auto* alias = ty.alias("Int", ty.i32()); auto alias = ty.alias("Int", ty.i32());
auto* cast = Construct(alias, 2.3f); auto* cast = Construct(alias, 2.3f);
WrapInFunction(cast); WrapInFunction(cast);
@ -975,7 +975,7 @@ TEST_F(SpvBuilderConstructorTest, Type_Array_2_Vec3) {
} }
TEST_F(SpvBuilderConstructorTest, Type_Struct) { TEST_F(SpvBuilderConstructorTest, Type_Struct) {
auto* s = Structure("my_struct", { auto s = Structure("my_struct", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}); });
@ -1125,7 +1125,7 @@ TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Array) {
} }
TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Struct) { TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Struct) {
auto* s = Structure("my_struct", {Member("a", ty.f32())}); auto s = Structure("my_struct", {Member("a", ty.f32())});
auto* t = Construct(s); auto* t = Construct(s);
WrapInFunction(t); WrapInFunction(t);
@ -1545,7 +1545,7 @@ TEST_F(SpvBuilderConstructorTest, IsConstructorConst_BitCastScalars) {
} }
TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct) { TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct) {
auto* s = Structure("my_struct", { auto s = Structure("my_struct", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}); });
@ -1561,7 +1561,7 @@ TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct) {
TEST_F(SpvBuilderConstructorTest, TEST_F(SpvBuilderConstructorTest,
IsConstructorConst_Struct_WithIdentSubExpression) { IsConstructorConst_Struct_WithIdentSubExpression) {
auto* s = Structure("my_struct", { auto s = Structure("my_struct", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}); });

View File

@ -191,7 +191,7 @@ TEST_F(BuilderTest, EntryPoint_SharedStruct) {
// return inputs.value; // return inputs.value;
// } // }
auto* interface = Structure( auto interface = Structure(
"Interface", "Interface",
{ {
Member("value", ty.f32(), ast::DecorationList{Location(1u)}), Member("value", ty.f32(), ast::DecorationList{Location(1u)}),

View File

@ -201,7 +201,7 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
// return; // return;
// } // }
auto* s = Structure("Data", {Member("d", ty.f32())}, auto s = Structure("Data", {Member("d", ty.f32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
sem::AccessControl ac(ast::AccessControl::kReadWrite, s); sem::AccessControl ac(ast::AccessControl::kReadWrite, s);

View File

@ -388,13 +388,13 @@ TEST_F(BuilderTest, GlobalVar_DeclReadOnly) {
// }; // };
// var b : [[access(read)]] A // var b : [[access(read)]] A
auto* A = Structure("A", auto A = Structure("A",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.i32()), Member("b", ty.i32()),
}, },
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = create<sem::AccessControl>(ast::AccessControl::kReadOnly, A); auto ac = ty.access(ast::AccessControl::kReadOnly, A);
auto* var = Global("b", ac, ast::StorageClass::kStorage); auto* var = Global("b", ac, ast::StorageClass::kStorage);
@ -427,10 +427,10 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasDeclReadOnly) {
// type B = A; // type B = A;
// var b : [[access(read)]] B // var b : [[access(read)]] B
auto* A = Structure("A", {Member("a", ty.i32())}, auto A = Structure("A", {Member("a", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* B = ty.alias("B", A); auto B = ty.alias("B", A);
auto* ac = create<sem::AccessControl>(ast::AccessControl::kReadOnly, B); auto ac = ty.access(ast::AccessControl::kReadOnly, B);
auto* var = Global("b", ac, ast::StorageClass::kStorage); auto* var = Global("b", ac, ast::StorageClass::kStorage);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -459,10 +459,10 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasAssignReadOnly) {
// type B = [[access(read)]] A; // type B = [[access(read)]] A;
// var b : B // var b : B
auto* A = Structure("A", {Member("a", ty.i32())}, auto A = Structure("A", {Member("a", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = create<sem::AccessControl>(ast::AccessControl::kReadOnly, A); auto ac = ty.access(ast::AccessControl::kReadOnly, A);
auto* B = ty.alias("B", ac); auto B = ty.alias("B", ac);
auto* var = Global("b", B, ast::StorageClass::kStorage); auto* var = Global("b", B, ast::StorageClass::kStorage);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -491,7 +491,7 @@ TEST_F(BuilderTest, GlobalVar_TwoVarDeclReadOnly) {
// var b : [[access(read)]] A // var b : [[access(read)]] A
// var c : [[access(read_write)]] A // var c : [[access(read_write)]] A
auto* A = Structure("A", {Member("a", ty.i32())}, auto A = Structure("A", {Member("a", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
sem::AccessControl read{ast::AccessControl::kReadOnly, A}; sem::AccessControl read{ast::AccessControl::kReadOnly, A};
sem::AccessControl rw{ast::AccessControl::kReadWrite, A}; sem::AccessControl rw{ast::AccessControl::kReadWrite, A};
@ -531,12 +531,10 @@ OpName %5 "c"
TEST_F(BuilderTest, GlobalVar_TextureStorageReadOnly) { TEST_F(BuilderTest, GlobalVar_TextureStorageReadOnly) {
// var<uniform_constant> a : [[access(read)]] texture_storage_2d<r32uint>; // var<uniform_constant> a : [[access(read)]] texture_storage_2d<r32uint>;
auto* subtype = auto type = ty.storage_texture(ast::TextureDimension::k2d,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Uint, Types()); ast::ImageFormat::kR32Uint);
auto* type = create<sem::StorageTexture>(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Uint, subtype);
auto* ac = create<sem::AccessControl>(ast::AccessControl::kReadOnly, type); auto ac = ty.access(ast::AccessControl::kReadOnly, type);
auto* var_a = Global("a", ac, ast::StorageClass::kUniformConstant); auto* var_a = Global("a", ac, ast::StorageClass::kUniformConstant);
@ -556,13 +554,11 @@ TEST_F(BuilderTest, GlobalVar_TextureStorageReadOnly) {
TEST_F(BuilderTest, GlobalVar_TextureStorageWriteOnly) { TEST_F(BuilderTest, GlobalVar_TextureStorageWriteOnly) {
// var<uniform_constant> a : [[access(write)]] texture_storage_2d<r32uint>; // var<uniform_constant> a : [[access(write)]] texture_storage_2d<r32uint>;
auto* subtype = auto type = ty.storage_texture(ast::TextureDimension::k2d,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Uint, Types()); ast::ImageFormat::kR32Uint);
auto* type = create<sem::StorageTexture>(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Uint, subtype);
Global("test_var", type, ast::StorageClass::kInput); Global("test_var", type, ast::StorageClass::kInput);
auto* ac = create<sem::AccessControl>(ast::AccessControl::kWriteOnly, type); auto ac = ty.access(ast::AccessControl::kWriteOnly, type);
auto* var_a = Global("a", ac, ast::StorageClass::kUniformConstant); auto* var_a = Global("a", ac, ast::StorageClass::kUniformConstant);
@ -585,17 +581,15 @@ TEST_F(BuilderTest, GlobalVar_TextureStorageWithDifferentAccess) {
// var<uniform_constant> a : [[access(read)]] texture_storage_2d<r32uint>; // var<uniform_constant> a : [[access(read)]] texture_storage_2d<r32uint>;
// var<uniform_constant> b : [[access(write)]] texture_storage_2d<r32uint>; // var<uniform_constant> b : [[access(write)]] texture_storage_2d<r32uint>;
auto* subtype = auto st = ty.storage_texture(ast::TextureDimension::k2d,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Uint, Types()); ast::ImageFormat::kR32Uint);
auto* st = create<sem::StorageTexture>(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Uint, subtype);
Global("test_var", st, ast::StorageClass::kInput); Global("test_var", st, ast::StorageClass::kInput);
auto* type_a = create<sem::AccessControl>(ast::AccessControl::kReadOnly, st); auto type_a = ty.access(ast::AccessControl::kReadOnly, st);
auto* var_a = Global("a", type_a, ast::StorageClass::kUniformConstant); auto* var_a = Global("a", type_a, ast::StorageClass::kUniformConstant);
auto* type_b = create<sem::AccessControl>(ast::AccessControl::kWriteOnly, st); auto type_b = ty.access(ast::AccessControl::kWriteOnly, st);
auto* var_b = Global("b", type_b, ast::StorageClass::kUniformConstant); auto* var_b = Global("b", type_b, ast::StorageClass::kUniformConstant);
spirv::Builder& b = Build(); spirv::Builder& b = Build();

View File

@ -1379,9 +1379,9 @@ OpFunctionEnd
} }
TEST_F(IntrinsicBuilderTest, Call_ArrayLength) { TEST_F(IntrinsicBuilderTest, Call_ArrayLength) {
auto* s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))}, auto s = Structure("my_struct", {Member(0, "a", ty.array<f32>(4))},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("b", ac, ast::StorageClass::kStorage, nullptr, Global("b", ac, ast::StorageClass::kStorage, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(1), create<ast::BindingDecoration>(1),
@ -1425,13 +1425,13 @@ TEST_F(IntrinsicBuilderTest, Call_ArrayLength) {
} }
TEST_F(IntrinsicBuilderTest, Call_ArrayLength_OtherMembersInStruct) { TEST_F(IntrinsicBuilderTest, Call_ArrayLength_OtherMembersInStruct) {
auto* s = Structure("my_struct", auto s = Structure("my_struct",
{ {
Member(0, "z", ty.f32()), Member(0, "z", ty.f32()),
Member(4, "a", ty.array<f32>(4)), Member(4, "a", ty.array<f32>(4)),
}, },
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("b", ac, ast::StorageClass::kStorage, nullptr, Global("b", ac, ast::StorageClass::kStorage, nullptr,
ast::DecorationList{ ast::DecorationList{
create<ast::BindingDecoration>(1), create<ast::BindingDecoration>(1),

View File

@ -27,7 +27,7 @@ namespace {
using BuilderTest_Type = TestHelper; using BuilderTest_Type = TestHelper;
TEST_F(BuilderTest_Type, GenerateAlias) { TEST_F(BuilderTest_Type, GenerateAlias) {
auto* alias_type = ty.alias("my_type", ty.f32()); auto alias_type = ty.alias("my_type", ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -43,7 +43,7 @@ TEST_F(BuilderTest_Type, GenerateAlias) {
TEST_F(BuilderTest_Type, ReturnsGeneratedAlias) { TEST_F(BuilderTest_Type, ReturnsGeneratedAlias) {
auto i32 = ty.i32(); auto i32 = ty.i32();
auto f32 = ty.f32(); auto f32 = ty.f32();
auto* alias_type = ty.alias("my_type", f32); auto alias_type = ty.alias("my_type", f32);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -59,9 +59,9 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedAlias) {
TEST_F(BuilderTest_Type, GenerateRuntimeArray) { TEST_F(BuilderTest_Type, GenerateRuntimeArray) {
auto ary = ty.array(ty.i32(), 0); auto ary = ty.array(ty.i32(), 0);
auto* str = Structure("S", {Member("x", ary)}, auto str = Structure("S", {Member("x", ary)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kReadOnly, str); auto ac = ty.access(ast::AccessControl::kReadOnly, str);
Global("a", ac, ast::StorageClass::kStorage); Global("a", ac, ast::StorageClass::kStorage);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -77,9 +77,9 @@ TEST_F(BuilderTest_Type, GenerateRuntimeArray) {
TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) { TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) {
auto ary = ty.array(ty.i32(), 0); auto ary = ty.array(ty.i32(), 0);
auto* str = Structure("S", {Member("x", ary)}, auto str = Structure("S", {Member("x", ary)},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* ac = ty.access(ast::AccessControl::kReadOnly, str); auto ac = ty.access(ast::AccessControl::kReadOnly, str);
Global("a", ac, ast::StorageClass::kStorage); Global("a", ac, ast::StorageClass::kStorage);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -285,7 +285,7 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) {
} }
TEST_F(BuilderTest_Type, GenerateStruct_Empty) { TEST_F(BuilderTest_Type, GenerateStruct_Empty) {
auto* s = Structure("S", {}); auto s = Structure("S", {});
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -301,7 +301,7 @@ TEST_F(BuilderTest_Type, GenerateStruct_Empty) {
} }
TEST_F(BuilderTest_Type, GenerateStruct) { TEST_F(BuilderTest_Type, GenerateStruct) {
auto* s = Structure("my_struct", {Member("a", ty.f32())}); auto s = Structure("my_struct", {Member("a", ty.f32())});
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -318,7 +318,7 @@ OpMemberName %1 0 "a"
} }
TEST_F(BuilderTest_Type, GenerateStruct_Decorated) { TEST_F(BuilderTest_Type, GenerateStruct_Decorated) {
auto* s = Structure("my_struct", {Member("a", ty.f32())}, auto s = Structure("my_struct", {Member("a", ty.f32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -339,7 +339,7 @@ OpMemberDecorate %1 0 Offset 0
} }
TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers) { TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.f32(), {MemberAlign(8)}), Member("b", ty.f32(), {MemberAlign(8)}),
}); });
@ -363,7 +363,7 @@ OpMemberDecorate %1 1 Offset 8
} }
TEST_F(BuilderTest_Type, GenerateStruct_NonLayout_Matrix) { TEST_F(BuilderTest_Type, GenerateStruct_NonLayout_Matrix) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.mat2x2<f32>()), Member("a", ty.mat2x2<f32>()),
Member("b", ty.mat2x3<f32>()), Member("b", ty.mat2x3<f32>()),
Member("c", ty.mat4x4<f32>()), Member("c", ty.mat4x4<f32>()),
@ -403,7 +403,7 @@ OpMemberDecorate %1 2 MatrixStride 16
TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutMatrix) { TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutMatrix) {
// We have to infer layout for matrix when it also has an offset. // We have to infer layout for matrix when it also has an offset.
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.mat2x2<f32>()), Member("a", ty.mat2x2<f32>()),
Member("b", ty.mat2x3<f32>()), Member("b", ty.mat2x3<f32>()),
Member("c", ty.mat4x4<f32>()), Member("c", ty.mat4x4<f32>()),
@ -449,8 +449,7 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutArraysOfMatrix) {
auto arr_arr_mat2x3 = ty.array(ty.mat2x3<f32>(), 1); // Doubly nested array auto arr_arr_mat2x3 = ty.array(ty.mat2x3<f32>(), 1); // Doubly nested array
auto rtarr_mat4x4 = ty.array(ty.mat4x4<f32>(), 0); // Runtime array auto rtarr_mat4x4 = ty.array(ty.mat4x4<f32>(), 0); // Runtime array
auto* s = auto s = Structure("S",
Structure("S",
{ {
Member("a", arr_mat2x2), Member("a", arr_mat2x2),
Member("b", arr_arr_mat2x3), Member("b", arr_arr_mat2x3),
@ -715,7 +714,7 @@ TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_f32) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_i32) { TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_i32) {
auto* s = create<sem::SampledTexture>(ast::TextureDimension::k1d, ty.i32()); auto s = ty.sampled_texture(ast::TextureDimension::k1d, ty.i32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -732,7 +731,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_i32) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_u32) { TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_u32) {
auto* s = create<sem::SampledTexture>(ast::TextureDimension::k1d, ty.u32()); auto s = ty.sampled_texture(ast::TextureDimension::k1d, ty.u32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -749,7 +748,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_u32) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_f32) { TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_f32) {
auto* s = create<sem::SampledTexture>(ast::TextureDimension::k1d, ty.f32()); auto s = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -766,7 +765,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_f32) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_2d) { TEST_F(BuilderTest_Type, SampledTexture_Generate_2d) {
auto* s = create<sem::SampledTexture>(ast::TextureDimension::k2d, ty.f32()); auto s = ty.sampled_texture(ast::TextureDimension::k2d, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -779,8 +778,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_2d) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_2d_array) { TEST_F(BuilderTest_Type, SampledTexture_Generate_2d_array) {
auto* s = auto s = ty.sampled_texture(ast::TextureDimension::k2dArray, ty.f32());
create<sem::SampledTexture>(ast::TextureDimension::k2dArray, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -793,7 +791,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_2d_array) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_3d) { TEST_F(BuilderTest_Type, SampledTexture_Generate_3d) {
auto* s = create<sem::SampledTexture>(ast::TextureDimension::k3d, ty.f32()); auto s = ty.sampled_texture(ast::TextureDimension::k3d, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -806,7 +804,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_3d) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) { TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) {
auto* s = create<sem::SampledTexture>(ast::TextureDimension::kCube, ty.f32()); auto s = ty.sampled_texture(ast::TextureDimension::kCube, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -820,8 +818,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) { TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) {
auto* s = auto s = ty.sampled_texture(ast::TextureDimension::kCubeArray, ty.f32());
create<sem::SampledTexture>(ast::TextureDimension::kCubeArray, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -837,10 +834,8 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) {
} }
TEST_F(BuilderTest_Type, StorageTexture_Generate_1d) { TEST_F(BuilderTest_Type, StorageTexture_Generate_1d) {
auto* subtype = auto s = ty.storage_texture(ast::TextureDimension::k1d,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()); ast::ImageFormat::kR32Float);
auto* s = create<sem::StorageTexture>(ast::TextureDimension::k1d,
ast::ImageFormat::kR32Float, subtype);
Global("test_var", s, ast::StorageClass::kInput); Global("test_var", s, ast::StorageClass::kInput);
@ -854,10 +849,8 @@ TEST_F(BuilderTest_Type, StorageTexture_Generate_1d) {
} }
TEST_F(BuilderTest_Type, StorageTexture_Generate_2d) { TEST_F(BuilderTest_Type, StorageTexture_Generate_2d) {
auto* subtype = auto s = ty.storage_texture(ast::TextureDimension::k2d,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()); ast::ImageFormat::kR32Float);
auto* s = create<sem::StorageTexture>(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Float, subtype);
Global("test_var", s, ast::StorageClass::kInput); Global("test_var", s, ast::StorageClass::kInput);
@ -871,10 +864,8 @@ TEST_F(BuilderTest_Type, StorageTexture_Generate_2d) {
} }
TEST_F(BuilderTest_Type, StorageTexture_Generate_2dArray) { TEST_F(BuilderTest_Type, StorageTexture_Generate_2dArray) {
auto* subtype = auto s = ty.storage_texture(ast::TextureDimension::k2dArray,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()); ast::ImageFormat::kR32Float);
auto* s = create<sem::StorageTexture>(ast::TextureDimension::k2dArray,
ast::ImageFormat::kR32Float, subtype);
Global("test_var", s, ast::StorageClass::kInput); Global("test_var", s, ast::StorageClass::kInput);
@ -888,10 +879,8 @@ TEST_F(BuilderTest_Type, StorageTexture_Generate_2dArray) {
} }
TEST_F(BuilderTest_Type, StorageTexture_Generate_3d) { TEST_F(BuilderTest_Type, StorageTexture_Generate_3d) {
auto* subtype = auto s = ty.storage_texture(ast::TextureDimension::k3d,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()); ast::ImageFormat::kR32Float);
auto* s = create<sem::StorageTexture>(ast::TextureDimension::k3d,
ast::ImageFormat::kR32Float, subtype);
Global("test_var", s, ast::StorageClass::kInput); Global("test_var", s, ast::StorageClass::kInput);
@ -906,10 +895,8 @@ TEST_F(BuilderTest_Type, StorageTexture_Generate_3d) {
TEST_F(BuilderTest_Type, TEST_F(BuilderTest_Type,
StorageTexture_Generate_SampledTypeFloat_Format_r32float) { StorageTexture_Generate_SampledTypeFloat_Format_r32float) {
auto* subtype = auto s = ty.storage_texture(ast::TextureDimension::k2d,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()); ast::ImageFormat::kR32Float);
auto* s = create<sem::StorageTexture>(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Float, subtype);
Global("test_var", s, ast::StorageClass::kInput); Global("test_var", s, ast::StorageClass::kInput);
@ -924,10 +911,8 @@ TEST_F(BuilderTest_Type,
TEST_F(BuilderTest_Type, TEST_F(BuilderTest_Type,
StorageTexture_Generate_SampledTypeSint_Format_r32sint) { StorageTexture_Generate_SampledTypeSint_Format_r32sint) {
auto* subtype = auto s = ty.storage_texture(ast::TextureDimension::k2d,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Sint, Types()); ast::ImageFormat::kR32Sint);
auto* s = create<sem::StorageTexture>(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Sint, subtype);
Global("test_var", s, ast::StorageClass::kInput); Global("test_var", s, ast::StorageClass::kInput);
@ -942,10 +927,8 @@ TEST_F(BuilderTest_Type,
TEST_F(BuilderTest_Type, TEST_F(BuilderTest_Type,
StorageTexture_Generate_SampledTypeUint_Format_r32uint) { StorageTexture_Generate_SampledTypeUint_Format_r32uint) {
auto* subtype = auto s = ty.storage_texture(ast::TextureDimension::k2d,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Uint, Types()); ast::ImageFormat::kR32Uint);
auto* s = create<sem::StorageTexture>(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Uint, subtype);
Global("test_var", s, ast::StorageClass::kInput); Global("test_var", s, ast::StorageClass::kInput);

View File

@ -22,7 +22,7 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitAlias_F32) { TEST_F(WgslGeneratorImplTest, EmitAlias_F32) {
auto* alias = ty.alias("a", ty.f32()); auto alias = ty.alias("a", ty.f32());
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
@ -31,12 +31,12 @@ TEST_F(WgslGeneratorImplTest, EmitAlias_F32) {
} }
TEST_F(WgslGeneratorImplTest, EmitConstructedType_Struct) { TEST_F(WgslGeneratorImplTest, EmitConstructedType_Struct) {
auto* s = Structure("A", { auto s = Structure("A", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.i32()), Member("b", ty.i32()),
}); });
auto* alias = ty.alias("B", s); auto alias = ty.alias("B", s);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -51,12 +51,12 @@ type B = A;
} }
TEST_F(WgslGeneratorImplTest, EmitAlias_ToStruct) { TEST_F(WgslGeneratorImplTest, EmitAlias_ToStruct) {
auto* s = Structure("A", { auto s = Structure("A", {
Member("a", ty.f32()), Member("a", ty.f32()),
Member("b", ty.i32()), Member("b", ty.i32()),
}); });
auto* alias = ty.alias("B", s); auto alias = ty.alias("B", s);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();

View File

@ -90,7 +90,7 @@ TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_UnusedVariable) {
TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_GlobalsInterleaved) { TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_GlobalsInterleaved) {
Global("a0", ty.f32(), ast::StorageClass::kPrivate); Global("a0", ty.f32(), ast::StorageClass::kPrivate);
auto* s0 = Structure("S0", {Member("a", ty.i32())}); auto s0 = Structure("S0", {Member("a", ty.i32())});
Func("func", {}, ty.f32(), Func("func", {}, ty.f32(),
{ {
@ -99,7 +99,7 @@ TEST_F(WgslGeneratorImplTest, Emit_EntryPoint_GlobalsInterleaved) {
Global("a1", ty.f32(), ast::StorageClass::kOutput); Global("a1", ty.f32(), ast::StorageClass::kOutput);
auto* s1 = Structure("S1", {Member("a", ty.i32())}); auto s1 = Structure("S1", {Member("a", ty.i32())});
Func("main", {}, ty.void_(), Func("main", {}, ty.void_(),
{ {

View File

@ -202,7 +202,7 @@ TEST_F(WgslGeneratorImplTest,
// return; // return;
// } // }
auto* s = Structure("Data", {Member("d", ty.f32())}, auto s = Structure("Data", {Member("d", ty.f32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
sem::AccessControl ac(ast::AccessControl::kReadWrite, s); sem::AccessControl ac(ast::AccessControl::kReadWrite, s);

View File

@ -48,7 +48,7 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalDeclAfterFunction) {
TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) { TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
Global("a0", ty.f32(), ast::StorageClass::kPrivate); Global("a0", ty.f32(), ast::StorageClass::kPrivate);
auto* s0 = Structure("S0", {Member("a", ty.i32())}); auto s0 = Structure("S0", {Member("a", ty.i32())});
Func("func", ast::VariableList{}, ty.f32(), Func("func", ast::VariableList{}, ty.f32(),
ast::StatementList{ ast::StatementList{
@ -58,7 +58,7 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
Global("a1", ty.f32(), ast::StorageClass::kOutput); Global("a1", ty.f32(), ast::StorageClass::kOutput);
auto* s1 = Structure("S1", {Member("a", ty.i32())}); auto s1 = Structure("S1", {Member("a", ty.i32())});
Func("main", ast::VariableList{}, ty.void_(), Func("main", ast::VariableList{}, ty.void_(),
ast::StatementList{ ast::StatementList{
@ -101,7 +101,7 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
} }
TEST_F(WgslGeneratorImplTest, Emit_Global_Sampler) { TEST_F(WgslGeneratorImplTest, Emit_Global_Sampler) {
Global("s", create<sem::Sampler>(ast::SamplerKind::kSampler), Global("s", ty.sampler(ast::SamplerKind::kSampler),
ast::StorageClass::kUniformConstant); ast::StorageClass::kUniformConstant);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -113,7 +113,7 @@ TEST_F(WgslGeneratorImplTest, Emit_Global_Sampler) {
} }
TEST_F(WgslGeneratorImplTest, Emit_Global_Texture) { TEST_F(WgslGeneratorImplTest, Emit_Global_Texture) {
auto* st = create<sem::SampledTexture>(ast::TextureDimension::k1d, ty.f32()); auto st = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
Global("t", ty.access(ast::AccessControl::kReadOnly, st), Global("t", ty.access(ast::AccessControl::kReadOnly, st),
ast::StorageClass::kUniformConstant); ast::StorageClass::kUniformConstant);

View File

@ -22,7 +22,7 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) { TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) {
auto* s = Structure("Data", {Member("mem", ty.f32())}); auto s = Structure("Data", {Member("mem", ty.f32())});
Global("str", s, ast::StorageClass::kPrivate); Global("str", s, ast::StorageClass::kPrivate);
auto* expr = MemberAccessor("str", "mem"); auto* expr = MemberAccessor("str", "mem");

View File

@ -27,7 +27,7 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitType_Alias) { TEST_F(WgslGeneratorImplTest, EmitType_Alias) {
auto* alias = ty.alias("alias", ty.f32()); auto alias = ty.alias("alias", ty.f32());
AST().AddConstructedType(alias); AST().AddConstructedType(alias);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -47,10 +47,10 @@ TEST_F(WgslGeneratorImplTest, EmitType_Array) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_Read) { TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_Read) {
auto* s = Structure("S", {Member("a", ty.i32())}, auto s = Structure("S", {Member("a", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kReadOnly, s); auto a = ty.access(ast::AccessControl::kReadOnly, s);
AST().AddConstructedType(ty.alias("make_type_reachable", a)); AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -60,10 +60,10 @@ TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_Read) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_ReadWrite) { TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_ReadWrite) {
auto* s = Structure("S", {Member("a", ty.i32())}, auto s = Structure("S", {Member("a", ty.i32())},
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto* a = ty.access(ast::AccessControl::kReadWrite, s); auto a = ty.access(ast::AccessControl::kReadWrite, s);
AST().AddConstructedType(ty.alias("make_type_reachable", a)); AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -73,10 +73,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_ReadWrite) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_Array_Decoration) { TEST_F(WgslGeneratorImplTest, EmitType_Array_Decoration) {
auto* a = create<sem::ArrayType>(ty.bool_(), 4, auto a = ty.array(ty.bool_(), 4, 16u);
ast::DecorationList{
create<ast::StrideDecoration>(16u),
});
AST().AddConstructedType(ty.alias("make_type_reachable", a)); AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -85,22 +82,8 @@ TEST_F(WgslGeneratorImplTest, EmitType_Array_Decoration) {
EXPECT_EQ(gen.result(), "[[stride(16)]] array<bool, 4>"); EXPECT_EQ(gen.result(), "[[stride(16)]] array<bool, 4>");
} }
TEST_F(WgslGeneratorImplTest, EmitType_Array_MultipleDecorations) {
auto* a = create<sem::ArrayType>(ty.bool_(), 4,
ast::DecorationList{
create<ast::StrideDecoration>(16u),
create<ast::StrideDecoration>(32u),
});
AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitType(a)) << gen.error();
EXPECT_EQ(gen.result(), "[[stride(16)]] [[stride(32)]] array<bool, 4>");
}
TEST_F(WgslGeneratorImplTest, EmitType_RuntimeArray) { TEST_F(WgslGeneratorImplTest, EmitType_RuntimeArray) {
auto* a = create<sem::ArrayType>(ty.bool_(), 0, ast::DecorationList{}); auto a = ty.array(ty.bool_(), 0);
AST().AddConstructedType(ty.alias("make_type_reachable", a)); AST().AddConstructedType(ty.alias("make_type_reachable", a));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -150,7 +133,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_Matrix) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_Pointer) { TEST_F(WgslGeneratorImplTest, EmitType_Pointer) {
auto* p = create<sem::Pointer>(ty.f32(), ast::StorageClass::kWorkgroup); auto p = ty.pointer<f32>(ast::StorageClass::kWorkgroup);
AST().AddConstructedType(ty.alias("make_type_reachable", p)); AST().AddConstructedType(ty.alias("make_type_reachable", p));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -160,7 +143,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_Pointer) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_Struct) { TEST_F(WgslGeneratorImplTest, EmitType_Struct) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32()), Member("b", ty.f32()),
}); });
@ -172,7 +155,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_Struct) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl) { TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32(), {MemberOffset(8)}), Member("a", ty.i32(), {MemberOffset(8)}),
Member("b", ty.f32(), {MemberOffset(16)}), Member("b", ty.f32(), {MemberOffset(16)}),
}); });
@ -192,7 +175,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl_WithSymbolCollisions) { TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl_WithSymbolCollisions) {
auto* s = auto s =
Structure("S", { Structure("S", {
Member("tint_0_padding", ty.i32(), {MemberOffset(8)}), Member("tint_0_padding", ty.i32(), {MemberOffset(8)}),
Member("tint_2_padding", ty.f32(), {MemberOffset(16)}), Member("tint_2_padding", ty.f32(), {MemberOffset(16)}),
@ -213,7 +196,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructOffsetDecl_WithSymbolCollisions) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_StructAlignDecl) { TEST_F(WgslGeneratorImplTest, EmitType_StructAlignDecl) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32(), {MemberAlign(8)}), Member("a", ty.i32(), {MemberAlign(8)}),
Member("b", ty.f32(), {MemberAlign(16)}), Member("b", ty.f32(), {MemberAlign(16)}),
}); });
@ -231,7 +214,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructAlignDecl) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_StructSizeDecl) { TEST_F(WgslGeneratorImplTest, EmitType_StructSizeDecl) {
auto* s = Structure("S", { auto s = Structure("S", {
Member("a", ty.i32(), {MemberSize(16)}), Member("a", ty.i32(), {MemberSize(16)}),
Member("b", ty.f32(), {MemberSize(32)}), Member("b", ty.f32(), {MemberSize(32)}),
}); });
@ -249,7 +232,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructSizeDecl) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithDecoration) { TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithDecoration) {
auto* s = Structure("S", auto s = Structure("S",
{ {
Member("a", ty.i32()), Member("a", ty.i32()),
Member("b", ty.f32(), {MemberAlign(8)}), Member("b", ty.f32(), {MemberAlign(8)}),
@ -272,7 +255,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithEntryPointDecorations) {
ast::DecorationList decos; ast::DecorationList decos;
decos.push_back(create<ast::StructBlockDecoration>()); decos.push_back(create<ast::StructBlockDecoration>());
auto* s = Structure( auto s = Structure(
"S", "S",
ast::StructMemberList{ ast::StructMemberList{
Member("a", ty.u32(), {Builtin(ast::Builtin::kVertexIndex)}), Member("a", ty.u32(), {Builtin(ast::Builtin::kVertexIndex)}),
@ -325,7 +308,7 @@ using WgslGenerator_DepthTextureTest = TestParamHelper<TextureData>;
TEST_P(WgslGenerator_DepthTextureTest, EmitType_DepthTexture) { TEST_P(WgslGenerator_DepthTextureTest, EmitType_DepthTexture) {
auto param = GetParam(); auto param = GetParam();
auto* d = create<sem::DepthTexture>(param.dim); auto d = ty.depth_texture(param.dim);
AST().AddConstructedType(ty.alias("make_type_reachable", d)); AST().AddConstructedType(ty.alias("make_type_reachable", d));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -347,7 +330,7 @@ using WgslGenerator_SampledTextureTest = TestParamHelper<TextureData>;
TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_F32) { TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_F32) {
auto param = GetParam(); auto param = GetParam();
auto* t = create<sem::SampledTexture>(param.dim, ty.f32()); auto t = ty.sampled_texture(param.dim, ty.f32());
AST().AddConstructedType(ty.alias("make_type_reachable", t)); AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -359,7 +342,7 @@ TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_F32) {
TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_I32) { TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_I32) {
auto param = GetParam(); auto param = GetParam();
auto* t = create<sem::SampledTexture>(param.dim, ty.i32()); auto t = ty.sampled_texture(param.dim, ty.i32());
AST().AddConstructedType(ty.alias("make_type_reachable", t)); AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -371,7 +354,7 @@ TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_I32) {
TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_U32) { TEST_P(WgslGenerator_SampledTextureTest, EmitType_SampledTexture_U32) {
auto param = GetParam(); auto param = GetParam();
auto* t = create<sem::SampledTexture>(param.dim, ty.u32()); auto t = ty.sampled_texture(param.dim, ty.u32());
AST().AddConstructedType(ty.alias("make_type_reachable", t)); AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -394,7 +377,7 @@ using WgslGenerator_MultiampledTextureTest = TestParamHelper<TextureData>;
TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_F32) { TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_F32) {
auto param = GetParam(); auto param = GetParam();
auto* t = create<sem::MultisampledTexture>(param.dim, ty.f32()); auto t = ty.multisampled_texture(param.dim, ty.f32());
AST().AddConstructedType(ty.alias("make_type_reachable", t)); AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -406,7 +389,7 @@ TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_F32) {
TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_I32) { TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_I32) {
auto param = GetParam(); auto param = GetParam();
auto* t = create<sem::MultisampledTexture>(param.dim, ty.i32()); auto t = ty.multisampled_texture(param.dim, ty.i32());
AST().AddConstructedType(ty.alias("make_type_reachable", t)); AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -418,7 +401,7 @@ TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_I32) {
TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_U32) { TEST_P(WgslGenerator_MultiampledTextureTest, EmitType_MultisampledTexture_U32) {
auto param = GetParam(); auto param = GetParam();
auto* t = create<sem::MultisampledTexture>(param.dim, ty.u32()); auto t = ty.multisampled_texture(param.dim, ty.u32());
AST().AddConstructedType(ty.alias("make_type_reachable", t)); AST().AddConstructedType(ty.alias("make_type_reachable", t));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -446,9 +429,8 @@ using WgslGenerator_StorageTextureTest = TestParamHelper<StorageTextureData>;
TEST_P(WgslGenerator_StorageTextureTest, EmitType_StorageTexture) { TEST_P(WgslGenerator_StorageTextureTest, EmitType_StorageTexture) {
auto param = GetParam(); auto param = GetParam();
auto* subtype = sem::StorageTexture::SubtypeFor(param.fmt, Types()); auto t = ty.storage_texture(param.dim, param.fmt);
auto* t = create<sem::StorageTexture>(param.dim, param.fmt, subtype); auto ac = ty.access(param.access, t);
auto* ac = ty.access(param.access, t);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -551,7 +533,7 @@ INSTANTIATE_TEST_SUITE_P(
ImageFormatData{ast::ImageFormat::kRgba32Float, "rgba32float"})); ImageFormatData{ast::ImageFormat::kRgba32Float, "rgba32float"}));
TEST_F(WgslGeneratorImplTest, EmitType_Sampler) { TEST_F(WgslGeneratorImplTest, EmitType_Sampler) {
auto* sampler = create<sem::Sampler>(ast::SamplerKind::kSampler); auto sampler = ty.sampler(ast::SamplerKind::kSampler);
AST().AddConstructedType(ty.alias("make_type_reachable", sampler)); AST().AddConstructedType(ty.alias("make_type_reachable", sampler));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -561,7 +543,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_Sampler) {
} }
TEST_F(WgslGeneratorImplTest, EmitType_SamplerComparison) { TEST_F(WgslGeneratorImplTest, EmitType_SamplerComparison) {
auto* sampler = create<sem::Sampler>(ast::SamplerKind::kComparisonSampler); auto sampler = ty.sampler(ast::SamplerKind::kComparisonSampler);
AST().AddConstructedType(ty.alias("make_type_reachable", sampler)); AST().AddConstructedType(ty.alias("make_type_reachable", sampler));
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();