writer/spirv: Begin migration to ast::Types

The SPIR-V writer doesn't really care much for ast::Types, so most of the work here is repointing the logic to fetch the resolved, semantic type.

Bug: tint:724
Change-Id: I7647e17b015bac8394bc0fc76daceb7c0a391a47
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49528
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton 2021-04-30 20:13:19 +00:00 committed by Commit Bot service account
parent 1737485a05
commit 44539d85b2
4 changed files with 127 additions and 100 deletions

View File

@ -508,7 +508,9 @@ uint32_t Builder::GenerateExpression(ast::Expression* expr) {
return 0; return 0;
} }
bool Builder::GenerateFunction(ast::Function* func) { bool Builder::GenerateFunction(ast::Function* func_ast) {
auto* func = builder_.Sem().Get(func_ast);
uint32_t func_type_id = GenerateFunctionTypeIfNeeded(func); uint32_t func_type_id = GenerateFunctionTypeIfNeeded(func);
if (func_type_id == 0) { if (func_type_id == 0) {
return false; return false;
@ -519,9 +521,9 @@ bool Builder::GenerateFunction(ast::Function* func) {
push_debug(spv::Op::OpName, push_debug(spv::Op::OpName,
{Operand::Int(func_id), {Operand::Int(func_id),
Operand::String(builder_.Symbols().NameFor(func->symbol()))}); Operand::String(builder_.Symbols().NameFor(func_ast->symbol()))});
auto ret_id = GenerateTypeIfNeeded(func->return_type()); auto ret_id = GenerateTypeIfNeeded(func->ReturnType());
if (ret_id == 0) { if (ret_id == 0) {
return false; return false;
} }
@ -534,51 +536,50 @@ bool Builder::GenerateFunction(ast::Function* func) {
Operand::Int(func_type_id)}}; Operand::Int(func_type_id)}};
InstructionList params; InstructionList params;
for (auto* param : func->params()) { for (auto* param : func->Parameters()) {
auto param_op = result_op(); auto param_op = result_op();
auto param_id = param_op.to_i(); auto param_id = param_op.to_i();
auto param_type_id = auto param_type_id = GenerateTypeIfNeeded(param->Type());
GenerateTypeIfNeeded(builder_.Sem().Get(param)->Type());
if (param_type_id == 0) { if (param_type_id == 0) {
return false; return false;
} }
push_debug(spv::Op::OpName, push_debug(spv::Op::OpName, {Operand::Int(param_id),
{Operand::Int(param_id), Operand::String(builder_.Symbols().NameFor(
Operand::String(builder_.Symbols().NameFor(param->symbol()))}); param->Declaration()->symbol()))});
params.push_back(Instruction{spv::Op::OpFunctionParameter, params.push_back(Instruction{spv::Op::OpFunctionParameter,
{Operand::Int(param_type_id), param_op}}); {Operand::Int(param_type_id), param_op}});
scope_stack_.set(param->symbol(), param_id); scope_stack_.set(param->Declaration()->symbol(), param_id);
} }
push_function(Function{definition_inst, result_op(), std::move(params)}); push_function(Function{definition_inst, result_op(), std::move(params)});
for (auto* stmt : *func->body()) { for (auto* stmt : *func_ast->body()) {
if (!GenerateStatement(stmt)) { if (!GenerateStatement(stmt)) {
return false; return false;
} }
} }
if (func->IsEntryPoint()) { if (func_ast->IsEntryPoint()) {
if (!GenerateEntryPoint(func, func_id)) { if (!GenerateEntryPoint(func_ast, func_id)) {
return false; return false;
} }
if (!GenerateExecutionModes(func, func_id)) { if (!GenerateExecutionModes(func_ast, func_id)) {
return false; return false;
} }
} }
scope_stack_.pop_scope(); scope_stack_.pop_scope();
func_symbol_to_id_[func->symbol()] = func_id; func_symbol_to_id_[func_ast->symbol()] = func_id;
return true; return true;
} }
uint32_t Builder::GenerateFunctionTypeIfNeeded(ast::Function* func) { uint32_t Builder::GenerateFunctionTypeIfNeeded(const sem::Function* func) {
auto val = type_name_to_id_.find(func->type_name()); auto val = type_name_to_id_.find(func->Declaration()->type_name());
if (val != type_name_to_id_.end()) { if (val != type_name_to_id_.end()) {
return val->second; return val->second;
} }
@ -586,15 +587,14 @@ uint32_t Builder::GenerateFunctionTypeIfNeeded(ast::Function* func) {
auto func_op = result_op(); auto func_op = result_op();
auto func_type_id = func_op.to_i(); auto func_type_id = func_op.to_i();
auto ret_id = GenerateTypeIfNeeded(func->return_type()); auto ret_id = GenerateTypeIfNeeded(func->ReturnType());
if (ret_id == 0) { if (ret_id == 0) {
return 0; return 0;
} }
OperandList ops = {func_op, Operand::Int(ret_id)}; OperandList ops = {func_op, Operand::Int(ret_id)};
for (auto* param : func->params()) { for (auto* param : func->Parameters()) {
auto param_type_id = auto param_type_id = GenerateTypeIfNeeded(param->Type());
GenerateTypeIfNeeded(builder_.Sem().Get(param)->Type());
if (param_type_id == 0) { if (param_type_id == 0) {
return 0; return 0;
} }
@ -603,7 +603,7 @@ uint32_t Builder::GenerateFunctionTypeIfNeeded(ast::Function* func) {
push_type(spv::Op::OpTypeFunction, std::move(ops)); push_type(spv::Op::OpTypeFunction, std::move(ops));
type_name_to_id_[func->type_name()] = func_type_id; type_name_to_id_[func->Declaration()->type_name()] = func_type_id;
return func_type_id; return func_type_id;
} }
@ -1217,7 +1217,7 @@ bool Builder::is_constructor_const(ast::Expression* expr, bool is_global_init) {
} }
auto* tc = constructor->As<ast::TypeConstructorExpression>(); auto* tc = constructor->As<ast::TypeConstructorExpression>();
auto* result_type = tc->type()->UnwrapAll(); auto* result_type = TypeOf(tc)->UnwrapAll();
for (size_t i = 0; i < tc->values().size(); ++i) { for (size_t i = 0; i < tc->values().size(); ++i) {
auto* e = tc->values()[i]; auto* e = tc->values()[i];
@ -1253,7 +1253,7 @@ bool Builder::is_constructor_const(ast::Expression* expr, bool is_global_init) {
} else if (auto* arr = subtype->As<sem::ArrayType>()) { } else if (auto* arr = subtype->As<sem::ArrayType>()) {
subtype = arr->type()->UnwrapAll(); subtype = arr->type()->UnwrapAll();
} else if (auto* str = subtype->As<sem::StructType>()) { } else if (auto* str = subtype->As<sem::StructType>()) {
subtype = str->impl()->members()[i]->type()->UnwrapAll(); subtype = builder_.Sem().Get(str)->Members()[i]->Type()->UnwrapAll();
} }
if (subtype != TypeOf(sc)->UnwrapAll()) { if (subtype != TypeOf(sc)->UnwrapAll()) {
return false; return false;
@ -1267,15 +1267,17 @@ uint32_t Builder::GenerateTypeConstructorExpression(
bool is_global_init) { bool is_global_init) {
auto& values = init->values(); auto& values = init->values();
auto* result_type = TypeOf(init);
// Generate the zero initializer if there are no values provided. // Generate the zero initializer if there are no values provided.
if (values.empty()) { if (values.empty()) {
return GenerateConstantNullIfNeeded(init->type()->UnwrapPtrIfNeeded()); return GenerateConstantNullIfNeeded(result_type->UnwrapPtrIfNeeded());
} }
std::ostringstream out; std::ostringstream out;
out << "__const"; out << "__const";
auto* result_type = init->type()->UnwrapAll(); result_type = result_type->UnwrapAll();
bool constructor_is_const = is_constructor_const(init, is_global_init); bool constructor_is_const = is_constructor_const(init, is_global_init);
if (has_error()) { if (has_error()) {
return 0; return 0;
@ -1298,7 +1300,7 @@ uint32_t Builder::GenerateTypeConstructorExpression(
return GenerateCastOrCopyOrPassthrough(result_type, values[0]); return GenerateCastOrCopyOrPassthrough(result_type, values[0]);
} }
auto type_id = GenerateTypeIfNeeded(init->type()); auto type_id = GenerateTypeIfNeeded(result_type);
if (type_id == 0) { if (type_id == 0) {
return 0; return 0;
} }
@ -1426,7 +1428,7 @@ uint32_t Builder::GenerateTypeConstructorExpression(
return result.to_i(); return result.to_i();
} }
uint32_t Builder::GenerateCastOrCopyOrPassthrough(sem::Type* to_type, uint32_t Builder::GenerateCastOrCopyOrPassthrough(const sem::Type* to_type,
ast::Expression* from_expr) { ast::Expression* from_expr) {
auto result = result_op(); auto result = result_op();
auto result_id = result.to_i(); auto result_id = result.to_i();
@ -1598,7 +1600,7 @@ uint32_t Builder::GenerateConstantIfNeeded(const ScalarConstant& constant) {
return result_id; return result_id;
} }
uint32_t Builder::GenerateConstantNullIfNeeded(sem::Type* type) { uint32_t Builder::GenerateConstantNullIfNeeded(const sem::Type* type) {
auto type_id = GenerateTypeIfNeeded(type); auto type_id = GenerateTypeIfNeeded(type);
if (type_id == 0) { if (type_id == 0) {
return 0; return 0;
@ -2413,12 +2415,15 @@ bool Builder::GenerateTextureIntrinsic(ast::CallExpression* call,
if (TypeOf(arg(Usage::kLevel))->Is<sem::I32>()) { if (TypeOf(arg(Usage::kLevel))->Is<sem::I32>()) {
// Depth textures have i32 parameters for the level, but SPIR-V expects // Depth textures have i32 parameters for the level, but SPIR-V expects
// F32. Cast. // F32. Cast.
auto* f32 = builder_.create<sem::F32>(); auto f32_type_id = GenerateTypeIfNeeded(builder_.create<sem::F32>());
ast::TypeConstructorExpression cast(ProgramID(), Source{}, f32, if (f32_type_id == 0) {
{arg(Usage::kLevel)}); return 0;
level = Operand::Int(GenerateExpression(&cast)); }
if (level.to_i() == 0) { level = result_op();
return false; if (!push_function_inst(
spv::Op::OpConvertSToF,
{Operand::Int(f32_type_id), level, gen_arg(Usage::kLevel)})) {
return 0;
} }
} else { } else {
level = gen_arg(Usage::kLevel); level = gen_arg(Usage::kLevel);
@ -2920,7 +2925,7 @@ bool Builder::GenerateVariableDeclStatement(ast::VariableDeclStatement* stmt) {
return GenerateFunctionVariable(stmt->variable()); return GenerateFunctionVariable(stmt->variable());
} }
uint32_t Builder::GenerateTypeIfNeeded(sem::Type* type) { uint32_t Builder::GenerateTypeIfNeeded(const sem::Type* type) {
if (type == nullptr) { if (type == nullptr) {
error_ = "attempting to generate type from null type"; error_ = "attempting to generate type from null type";
return 0; return 0;
@ -3002,7 +3007,7 @@ uint32_t Builder::GenerateTypeIfNeeded(sem::Type* type) {
} }
// TODO(tommek): Cover multisampled textures here when they're included in AST // TODO(tommek): Cover multisampled textures here when they're included in AST
bool Builder::GenerateTextureType(sem::Texture* texture, bool Builder::GenerateTextureType(const sem::Texture* texture,
const Operand& result) { const Operand& result) {
uint32_t array_literal = 0u; uint32_t array_literal = 0u;
const auto dim = texture->dim(); const auto dim = texture->dim();
@ -3080,7 +3085,8 @@ bool Builder::GenerateTextureType(sem::Texture* texture,
return true; return true;
} }
bool Builder::GenerateArrayType(sem::ArrayType* ary, const Operand& result) { bool Builder::GenerateArrayType(const sem::ArrayType* ary,
const Operand& result) {
auto elem_type = GenerateTypeIfNeeded(ary->type()); auto elem_type = GenerateTypeIfNeeded(ary->type());
if (elem_type == 0) { if (elem_type == 0) {
return false; return false;
@ -3110,7 +3116,8 @@ bool Builder::GenerateArrayType(sem::ArrayType* ary, const Operand& result) {
return true; return true;
} }
bool Builder::GenerateMatrixType(sem::Matrix* mat, const Operand& result) { bool Builder::GenerateMatrixType(const sem::Matrix* mat,
const Operand& result) {
sem::Vector col_type(mat->type(), mat->rows()); sem::Vector col_type(mat->type(), mat->rows());
auto col_type_id = GenerateTypeIfNeeded(&col_type); auto col_type_id = GenerateTypeIfNeeded(&col_type);
if (has_error()) { if (has_error()) {
@ -3122,7 +3129,8 @@ bool Builder::GenerateMatrixType(sem::Matrix* mat, const Operand& result) {
return true; return true;
} }
bool Builder::GeneratePointerType(sem::Pointer* ptr, const Operand& result) { bool Builder::GeneratePointerType(const sem::Pointer* ptr,
const Operand& result) {
auto pointee_id = GenerateTypeIfNeeded(ptr->type()); auto pointee_id = GenerateTypeIfNeeded(ptr->type());
if (pointee_id == 0) { if (pointee_id == 0) {
return false; return false;
@ -3140,7 +3148,7 @@ bool Builder::GeneratePointerType(sem::Pointer* ptr, const Operand& result) {
return true; return true;
} }
bool Builder::GenerateStructType(sem::StructType* struct_type, bool Builder::GenerateStructType(const sem::StructType* struct_type,
ast::AccessControl::Access access_control, ast::AccessControl::Access access_control,
const Operand& result) { const Operand& result) {
auto struct_id = result.to_i(); auto struct_id = result.to_i();
@ -3212,7 +3220,7 @@ uint32_t Builder::GenerateStructMember(uint32_t struct_id,
Operand::Int(SpvDecorationOffset), Operand::Int(sem_member->Offset())}); Operand::Int(SpvDecorationOffset), Operand::Int(sem_member->Offset())});
// Infer and emit matrix layout. // Infer and emit matrix layout.
auto* matrix_type = GetNestedMatrixType(member->type()); auto* matrix_type = GetNestedMatrixType(sem_member->Type());
if (matrix_type) { if (matrix_type) {
push_annot(spv::Op::OpMemberDecorate, push_annot(spv::Op::OpMemberDecorate,
{Operand::Int(struct_id), Operand::Int(idx), {Operand::Int(struct_id), Operand::Int(idx),
@ -3229,10 +3237,11 @@ uint32_t Builder::GenerateStructMember(uint32_t struct_id,
Operand::Int(effective_row_count * scalar_elem_size)}); Operand::Int(effective_row_count * scalar_elem_size)});
} }
return GenerateTypeIfNeeded(member->type()); return GenerateTypeIfNeeded(sem_member->Type());
} }
bool Builder::GenerateVectorType(sem::Vector* vec, const Operand& result) { bool Builder::GenerateVectorType(const sem::Vector* vec,
const Operand& result) {
auto type_id = GenerateTypeIfNeeded(vec->type()); auto type_id = GenerateTypeIfNeeded(vec->type());
if (has_error()) { if (has_error()) {
return false; return false;

View File

@ -258,7 +258,7 @@ class Builder {
/// Generates a function type if not already created /// Generates a function type if not already created
/// @param func the function to generate for /// @param func the function to generate for
/// @returns the ID to use for the function type. Returns 0 on failure. /// @returns the ID to use for the function type. Returns 0 on failure.
uint32_t GenerateFunctionTypeIfNeeded(ast::Function* func); uint32_t GenerateFunctionTypeIfNeeded(const sem::Function* func);
/// Generates access control annotations if needed /// Generates access control annotations if needed
/// @param type the type to generate for /// @param type the type to generate for
/// @param struct_id the struct id /// @param struct_id the struct id
@ -381,7 +381,7 @@ class Builder {
/// @param to_type the type we're casting too /// @param to_type the type we're casting too
/// @param from_expr the expression to cast /// @param from_expr the expression to cast
/// @returns the expression ID on success or 0 otherwise /// @returns the expression ID on success or 0 otherwise
uint32_t GenerateCastOrCopyOrPassthrough(sem::Type* to_type, uint32_t GenerateCastOrCopyOrPassthrough(const sem::Type* to_type,
ast::Expression* from_expr); ast::Expression* from_expr);
/// Generates a loop statement /// Generates a loop statement
/// @param stmt the statement to generate /// @param stmt the statement to generate
@ -423,33 +423,33 @@ class Builder {
/// Generates a type if not already created /// Generates a type if not already created
/// @param type the type to create /// @param type the type to create
/// @returns the ID to use for the given type. Returns 0 on unknown type. /// @returns the ID to use for the given type. Returns 0 on unknown type.
uint32_t GenerateTypeIfNeeded(sem::Type* type); uint32_t GenerateTypeIfNeeded(const sem::Type* type);
/// Generates a texture type declaration /// Generates a texture type declaration
/// @param texture the texture to generate /// @param texture the texture to generate
/// @param result the result operand /// @param result the result operand
/// @returns true if the texture was successfully generated /// @returns true if the texture was successfully generated
bool GenerateTextureType(sem::Texture* texture, const Operand& result); bool GenerateTextureType(const sem::Texture* texture, const Operand& result);
/// Generates an array type declaration /// Generates an array type declaration
/// @param ary the array to generate /// @param ary the array to generate
/// @param result the result operand /// @param result the result operand
/// @returns true if the array was successfully generated /// @returns true if the array was successfully generated
bool GenerateArrayType(sem::ArrayType* ary, const Operand& result); bool GenerateArrayType(const sem::ArrayType* ary, const Operand& result);
/// Generates a matrix type declaration /// Generates a matrix type declaration
/// @param mat the matrix to generate /// @param mat the matrix to generate
/// @param result the result operand /// @param result the result operand
/// @returns true if the matrix was successfully generated /// @returns true if the matrix was successfully generated
bool GenerateMatrixType(sem::Matrix* mat, const Operand& result); bool GenerateMatrixType(const sem::Matrix* mat, const Operand& result);
/// Generates a pointer type declaration /// Generates a pointer type declaration
/// @param ptr the pointer type to generate /// @param ptr the pointer type to generate
/// @param result the result operand /// @param result the result operand
/// @returns true if the pointer was successfully generated /// @returns true if the pointer was successfully generated
bool GeneratePointerType(sem::Pointer* ptr, const Operand& result); bool GeneratePointerType(const sem::Pointer* ptr, const Operand& result);
/// Generates a vector type declaration /// Generates a vector type declaration
/// @param struct_type the vector to generate /// @param struct_type the vector to generate
/// @param access_control the access controls to assign to the struct /// @param access_control the access controls to assign to the struct
/// @param result the result operand /// @param result the result operand
/// @returns true if the vector was successfully generated /// @returns true if the vector was successfully generated
bool GenerateStructType(sem::StructType* struct_type, bool GenerateStructType(const sem::StructType* struct_type,
ast::AccessControl::Access access_control, ast::AccessControl::Access access_control,
const Operand& result); const Operand& result);
/// Generates a struct member /// Generates a struct member
@ -468,7 +468,7 @@ class Builder {
/// @param vec the vector to generate /// @param vec the vector to generate
/// @param result the result operand /// @param result the result operand
/// @returns true if the vector was successfully generated /// @returns true if the vector was successfully generated
bool GenerateVectorType(sem::Vector* vec, const Operand& result); bool GenerateVectorType(const sem::Vector* vec, const Operand& result);
/// Converts AST image format to SPIR-V and pushes an appropriate capability. /// Converts AST image format to SPIR-V and pushes an appropriate capability.
/// @param format AST image format type /// @param format AST image format type
@ -500,7 +500,7 @@ class Builder {
/// Generates a constant-null of the given type, if needed /// Generates a constant-null of the given type, if needed
/// @param type the type of the constant null to generate. /// @param type the type of the constant null to generate.
/// @returns the ID on success or 0 on failure /// @returns the ID on success or 0 on failure
uint32_t GenerateConstantNullIfNeeded(sem::Type* type); uint32_t GenerateConstantNullIfNeeded(const sem::Type* type);
ProgramBuilder builder_; ProgramBuilder builder_;
std::string error_; std::string error_;

View File

@ -430,6 +430,7 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasDeclReadOnly) {
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);
AST().AddConstructedType(B);
auto ac = ty.access(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);
@ -463,6 +464,7 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasAssignReadOnly) {
{create<ast::StructBlockDecoration>()}); {create<ast::StructBlockDecoration>()});
auto ac = ty.access(ast::AccessControl::kReadOnly, A); auto ac = ty.access(ast::AccessControl::kReadOnly, A);
auto B = ty.alias("B", ac); auto B = ty.alias("B", ac);
AST().AddConstructedType(B);
auto* var = Global("b", B, ast::StorageClass::kStorage); auto* var = Global("b", B, ast::StorageClass::kStorage);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -580,13 +582,14 @@ 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 st = ty.storage_texture(ast::TextureDimension::k2d, auto type_a = ty.access(ast::AccessControl::kReadOnly,
ast::ImageFormat::kR32Uint); ty.storage_texture(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Uint));
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 = ty.access(ast::AccessControl::kWriteOnly, st); auto type_b = ty.access(ast::AccessControl::kWriteOnly,
ty.storage_texture(ast::TextureDimension::k2d,
ast::ImageFormat::kR32Uint));
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

@ -499,7 +499,7 @@ OpDecorate %11 ArrayStride 64
} }
TEST_F(BuilderTest_Type, GenerateU32) { TEST_F(BuilderTest_Type, GenerateU32) {
auto u32 = ty.u32(); auto* u32 = create<sem::U32>();
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -513,7 +513,7 @@ TEST_F(BuilderTest_Type, GenerateU32) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedU32) { TEST_F(BuilderTest_Type, ReturnsGeneratedU32) {
auto u32 = ty.u32(); auto* u32 = create<sem::U32>();
auto f32 = ty.f32(); auto f32 = ty.f32();
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -527,7 +527,7 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedU32) {
} }
TEST_F(BuilderTest_Type, GenerateVector) { TEST_F(BuilderTest_Type, GenerateVector) {
auto vec = ty.vec3<f32>(); auto* vec = create<sem::Vector>(create<sem::F32>(), 3);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -556,7 +556,7 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedVector) {
} }
TEST_F(BuilderTest_Type, GenerateVoid) { TEST_F(BuilderTest_Type, GenerateVoid) {
auto void_ = ty.void_(); auto* void_ = create<sem::Void>();
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -570,7 +570,7 @@ TEST_F(BuilderTest_Type, GenerateVoid) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedVoid) { TEST_F(BuilderTest_Type, ReturnsGeneratedVoid) {
auto void_ = ty.void_(); auto* void_ = create<sem::Void>();
auto i32 = ty.i32(); auto i32 = ty.i32();
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -616,11 +616,11 @@ INSTANTIATE_TEST_SUITE_P(
PtrData{ast::StorageClass::kFunction, SpvStorageClassFunction})); PtrData{ast::StorageClass::kFunction, SpvStorageClassFunction}));
TEST_F(BuilderTest_Type, DepthTexture_Generate_2d) { TEST_F(BuilderTest_Type, DepthTexture_Generate_2d) {
sem::DepthTexture two_d(ast::TextureDimension::k2d); auto* two_d = create<sem::DepthTexture>(ast::TextureDimension::k2d);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
auto id_two_d = b.GenerateTypeIfNeeded(&two_d); auto id_two_d = b.GenerateTypeIfNeeded(two_d);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(1u, id_two_d); EXPECT_EQ(1u, id_two_d);
@ -630,11 +630,12 @@ TEST_F(BuilderTest_Type, DepthTexture_Generate_2d) {
} }
TEST_F(BuilderTest_Type, DepthTexture_Generate_2dArray) { TEST_F(BuilderTest_Type, DepthTexture_Generate_2dArray) {
sem::DepthTexture two_d_array(ast::TextureDimension::k2dArray); auto* two_d_array =
create<sem::DepthTexture>(ast::TextureDimension::k2dArray);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
auto id_two_d_array = b.GenerateTypeIfNeeded(&two_d_array); auto id_two_d_array = b.GenerateTypeIfNeeded(two_d_array);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(1u, id_two_d_array); EXPECT_EQ(1u, id_two_d_array);
@ -644,11 +645,11 @@ TEST_F(BuilderTest_Type, DepthTexture_Generate_2dArray) {
} }
TEST_F(BuilderTest_Type, DepthTexture_Generate_Cube) { TEST_F(BuilderTest_Type, DepthTexture_Generate_Cube) {
sem::DepthTexture cube(ast::TextureDimension::kCube); auto* cube = create<sem::DepthTexture>(ast::TextureDimension::kCube);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
auto id_cube = b.GenerateTypeIfNeeded(&cube); auto id_cube = b.GenerateTypeIfNeeded(cube);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(1u, id_cube); EXPECT_EQ(1u, id_cube);
@ -659,11 +660,12 @@ TEST_F(BuilderTest_Type, DepthTexture_Generate_Cube) {
} }
TEST_F(BuilderTest_Type, DepthTexture_Generate_CubeArray) { TEST_F(BuilderTest_Type, DepthTexture_Generate_CubeArray) {
sem::DepthTexture cube_array(ast::TextureDimension::kCubeArray); auto* cube_array =
create<sem::DepthTexture>(ast::TextureDimension::kCubeArray);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
auto id_cube_array = b.GenerateTypeIfNeeded(&cube_array); auto id_cube_array = b.GenerateTypeIfNeeded(cube_array);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(1u, id_cube_array); EXPECT_EQ(1u, id_cube_array);
@ -676,11 +678,12 @@ TEST_F(BuilderTest_Type, DepthTexture_Generate_CubeArray) {
} }
TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_i32) { TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_i32) {
sem::MultisampledTexture ms(ast::TextureDimension::k2d, ty.i32()); auto i32 = ty.i32();
auto* ms = create<sem::MultisampledTexture>(ast::TextureDimension::k2d, i32);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
EXPECT_EQ(1u, b.GenerateTypeIfNeeded(&ms)); EXPECT_EQ(1u, b.GenerateTypeIfNeeded(ms));
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeImage %2 2D 0 0 1 1 Unknown %1 = OpTypeImage %2 2D 0 0 1 1 Unknown
@ -688,11 +691,12 @@ TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_i32) {
} }
TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_u32) { TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_u32) {
sem::MultisampledTexture ms(ast::TextureDimension::k2d, ty.u32()); auto* u32 = create<sem::U32>();
auto* ms = create<sem::MultisampledTexture>(ast::TextureDimension::k2d, u32);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(&ms), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(ms), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), EXPECT_EQ(DumpInstructions(b.types()),
R"(%2 = OpTypeInt 32 0 R"(%2 = OpTypeInt 32 0
@ -701,11 +705,12 @@ TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_u32) {
} }
TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_f32) { TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_f32) {
sem::MultisampledTexture ms(ast::TextureDimension::k2d, ty.f32()); auto f32 = ty.f32();
auto* ms = create<sem::MultisampledTexture>(ast::TextureDimension::k2d, f32);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(&ms), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(ms), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), EXPECT_EQ(DumpInstructions(b.types()),
R"(%2 = OpTypeFloat 32 R"(%2 = OpTypeFloat 32
@ -714,7 +719,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 = ty.sampled_texture(ast::TextureDimension::k1d, ty.i32()); auto* s = create<sem::SampledTexture>(ast::TextureDimension::k1d, ty.i32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -731,7 +736,8 @@ 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 = ty.sampled_texture(ast::TextureDimension::k1d, ty.u32()); auto* u32 = create<sem::U32>();
auto* s = create<sem::SampledTexture>(ast::TextureDimension::k1d, u32);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -748,7 +754,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 = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32()); auto* s = create<sem::SampledTexture>(ast::TextureDimension::k1d, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -765,7 +771,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 = ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()); auto* s = create<sem::SampledTexture>(ast::TextureDimension::k2d, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -778,7 +784,8 @@ 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 = ty.sampled_texture(ast::TextureDimension::k2dArray, ty.f32()); auto* s =
create<sem::SampledTexture>(ast::TextureDimension::k2dArray, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -791,7 +798,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 = ty.sampled_texture(ast::TextureDimension::k3d, ty.f32()); auto* s = create<sem::SampledTexture>(ast::TextureDimension::k3d, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -804,7 +811,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_3d) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) { TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) {
auto s = ty.sampled_texture(ast::TextureDimension::kCube, ty.f32()); auto* s = create<sem::SampledTexture>(ast::TextureDimension::kCube, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -818,7 +825,8 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) { TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) {
auto s = ty.sampled_texture(ast::TextureDimension::kCubeArray, ty.f32()); auto* s =
create<sem::SampledTexture>(ast::TextureDimension::kCubeArray, ty.f32());
spirv::Builder& b = Build(); spirv::Builder& b = Build();
@ -834,8 +842,9 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) {
} }
TEST_F(BuilderTest_Type, StorageTexture_Generate_1d) { TEST_F(BuilderTest_Type, StorageTexture_Generate_1d) {
auto s = ty.storage_texture(ast::TextureDimension::k1d, auto* s = create<sem::StorageTexture>(
ast::ImageFormat::kR32Float); ast::TextureDimension::k1d, ast::ImageFormat::kR32Float,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()));
auto ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("test_var", ac, ast::StorageClass::kInput); Global("test_var", ac, ast::StorageClass::kInput);
@ -850,8 +859,9 @@ TEST_F(BuilderTest_Type, StorageTexture_Generate_1d) {
} }
TEST_F(BuilderTest_Type, StorageTexture_Generate_2d) { TEST_F(BuilderTest_Type, StorageTexture_Generate_2d) {
auto s = ty.storage_texture(ast::TextureDimension::k2d, auto* s = create<sem::StorageTexture>(
ast::ImageFormat::kR32Float); ast::TextureDimension::k2d, ast::ImageFormat::kR32Float,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()));
auto ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("test_var", ac, ast::StorageClass::kInput); Global("test_var", ac, ast::StorageClass::kInput);
@ -866,8 +876,9 @@ TEST_F(BuilderTest_Type, StorageTexture_Generate_2d) {
} }
TEST_F(BuilderTest_Type, StorageTexture_Generate_2dArray) { TEST_F(BuilderTest_Type, StorageTexture_Generate_2dArray) {
auto s = ty.storage_texture(ast::TextureDimension::k2dArray, auto* s = create<sem::StorageTexture>(
ast::ImageFormat::kR32Float); ast::TextureDimension::k2dArray, ast::ImageFormat::kR32Float,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()));
auto ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("test_var", ac, ast::StorageClass::kInput); Global("test_var", ac, ast::StorageClass::kInput);
@ -882,8 +893,9 @@ TEST_F(BuilderTest_Type, StorageTexture_Generate_2dArray) {
} }
TEST_F(BuilderTest_Type, StorageTexture_Generate_3d) { TEST_F(BuilderTest_Type, StorageTexture_Generate_3d) {
auto s = ty.storage_texture(ast::TextureDimension::k3d, auto* s = create<sem::StorageTexture>(
ast::ImageFormat::kR32Float); ast::TextureDimension::k3d, ast::ImageFormat::kR32Float,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()));
auto ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("test_var", ac, ast::StorageClass::kInput); Global("test_var", ac, ast::StorageClass::kInput);
@ -899,8 +911,9 @@ 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 s = ty.storage_texture(ast::TextureDimension::k2d, auto* s = create<sem::StorageTexture>(
ast::ImageFormat::kR32Float); ast::TextureDimension::k2d, ast::ImageFormat::kR32Float,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Float, Types()));
auto ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("test_var", ac, ast::StorageClass::kInput); Global("test_var", ac, ast::StorageClass::kInput);
@ -916,8 +929,9 @@ TEST_F(BuilderTest_Type,
TEST_F(BuilderTest_Type, TEST_F(BuilderTest_Type,
StorageTexture_Generate_SampledTypeSint_Format_r32sint) { StorageTexture_Generate_SampledTypeSint_Format_r32sint) {
auto s = ty.storage_texture(ast::TextureDimension::k2d, auto* s = create<sem::StorageTexture>(
ast::ImageFormat::kR32Sint); ast::TextureDimension::k2d, ast::ImageFormat::kR32Sint,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Sint, Types()));
auto ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("test_var", ac, ast::StorageClass::kInput); Global("test_var", ac, ast::StorageClass::kInput);
@ -933,8 +947,9 @@ TEST_F(BuilderTest_Type,
TEST_F(BuilderTest_Type, TEST_F(BuilderTest_Type,
StorageTexture_Generate_SampledTypeUint_Format_r32uint) { StorageTexture_Generate_SampledTypeUint_Format_r32uint) {
auto s = ty.storage_texture(ast::TextureDimension::k2d, auto* s = create<sem::StorageTexture>(
ast::ImageFormat::kR32Uint); ast::TextureDimension::k2d, ast::ImageFormat::kR32Uint,
sem::StorageTexture::SubtypeFor(ast::ImageFormat::kR32Uint, Types()));
auto ac = ty.access(ast::AccessControl::kReadOnly, s); auto ac = ty.access(ast::AccessControl::kReadOnly, s);
Global("test_var", ac, ast::StorageClass::kInput); Global("test_var", ac, ast::StorageClass::kInput);