Convert MSL generator to unsafe namer.

This Cl updates the MSL generator to use the unsafe namer internally.

Change-Id: Ibeea747da1d7675c05a0dcb2416fbd491bb5d64b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/36581
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
dan sinclair 2021-01-11 16:24:32 +00:00 committed by dan sinclair
parent 1d9935cf37
commit 05b64849b2
13 changed files with 180 additions and 954 deletions

View File

@ -590,8 +590,6 @@ source_set("libtint_msl_writer_src") {
"src/writer/msl/generator.h",
"src/writer/msl/generator_impl.cc",
"src/writer/msl/generator_impl.h",
"src/writer/msl/namer.cc",
"src/writer/msl/namer.h",
]
configs += [ ":tint_common_config" ]
@ -1147,7 +1145,6 @@ source_set("tint_unittests_msl_writer_src") {
"src/writer/msl/generator_impl_type_test.cc",
"src/writer/msl/generator_impl_unary_op_test.cc",
"src/writer/msl/generator_impl_variable_decl_statement_test.cc",
"src/writer/msl/namer_test.cc",
"src/writer/msl/test_helper.h",
]

View File

@ -343,8 +343,6 @@ if(${TINT_BUILD_MSL_WRITER})
writer/msl/generator.h
writer/msl/generator_impl.cc
writer/msl/generator_impl.h
writer/msl/namer.cc
writer/msl/namer.h
)
endif()
@ -693,7 +691,6 @@ if(${TINT_BUILD_TESTS})
writer/msl/generator_impl_type_test.cc
writer/msl/generator_impl_unary_op_test.cc
writer/msl/generator_impl_variable_decl_statement_test.cc
writer/msl/namer_test.cc
writer/msl/test_helper.h
)
endif()

View File

@ -97,21 +97,12 @@ uint32_t adjust_for_alignment(uint32_t count, uint32_t alignment) {
} // namespace
GeneratorImpl::GeneratorImpl(ast::Module* module)
: TextGenerator(), module_(module) {}
: TextGenerator(),
module_(module),
namer_(std::make_unique<UnsafeNamer>(module)) {}
GeneratorImpl::~GeneratorImpl() = default;
std::string GeneratorImpl::generate_name(const std::string& prefix) {
std::string name = prefix;
uint32_t i = 0;
while (namer_.IsMapped(name)) {
name = prefix + "_" + std::to_string(i);
++i;
}
namer_.RegisterRemappedName(name);
return name;
}
bool GeneratorImpl::Generate() {
out_ << "#include <metal_stdlib>" << std::endl << std::endl;
@ -256,10 +247,10 @@ bool GeneratorImpl::EmitConstructedType(const ast::type::Type* ty) {
if (auto* alias = ty->As<ast::type::Alias>()) {
out_ << "typedef ";
if (!EmitType(alias->type(), "")) {
if (!EmitType(alias->type(), Symbol())) {
return false;
}
out_ << " " << namer_.NameFor(alias->name()) << ";" << std::endl;
out_ << " " << namer_->NameFor(alias->symbol()) << ";" << std::endl;
} else if (auto* str = ty->As<ast::type::Struct>()) {
if (!EmitStructType(str)) {
return false;
@ -288,7 +279,7 @@ bool GeneratorImpl::EmitArrayAccessor(ast::ArrayAccessorExpression* expr) {
bool GeneratorImpl::EmitBitcast(ast::BitcastExpression* expr) {
out_ << "as_type<";
if (!EmitType(expr->type(), "")) {
if (!EmitType(expr->type(), Symbol())) {
return false;
}
@ -504,13 +495,13 @@ bool GeneratorImpl::EmitCall(ast::CallExpression* expr) {
// // We create variables to hold the two parameters in case they're
// // function calls with side effects.
// auto* param0 = param[0].get();
// auto* name0 = generate_name("outer_product_expr_0");
// auto* name0 = namer_->GenerateName("outer_product_expr_0");
// auto* param1 = param[1].get();
// auto* name1 = generate_name("outer_product_expr_1");
// auto* name1 = namer_->GenerateName("outer_product_expr_1");
// make_indent();
// if (!EmitType(expr->result_type(), "")) {
// if (!EmitType(expr->result_type(), Symbol())) {
// return false;
// }
// out_ << "(";
@ -917,7 +908,7 @@ bool GeneratorImpl::EmitTypeConstructor(ast::TypeConstructorExpression* expr) {
if (expr->type()->Is<ast::type::Array>()) {
out_ << "{";
} else {
if (!EmitType(expr->type(), "")) {
if (!EmitType(expr->type(), Symbol())) {
return false;
}
out_ << "(";
@ -1025,9 +1016,9 @@ bool GeneratorImpl::EmitEntryPointData(ast::Function* func) {
}
if (!in_locations.empty()) {
auto in_struct_name =
generate_name(func->name() + "_" + kInStructNameSuffix);
auto in_var_name = generate_name(kTintStructInVarPrefix);
auto in_struct_name = namer_->GenerateName(namer_->NameFor(func->symbol()) +
"_" + kInStructNameSuffix);
auto in_var_name = namer_->GenerateName(kTintStructInVarPrefix);
ep_sym_to_in_data_[func->symbol().value()] = {in_struct_name, in_var_name};
make_indent();
@ -1040,7 +1031,7 @@ bool GeneratorImpl::EmitEntryPointData(ast::Function* func) {
uint32_t loc = data.second;
make_indent();
if (!EmitType(var->type(), var->name())) {
if (!EmitType(var->type(), var->symbol())) {
return false;
}
@ -1062,9 +1053,9 @@ bool GeneratorImpl::EmitEntryPointData(ast::Function* func) {
}
if (!out_variables.empty()) {
auto out_struct_name =
generate_name(func->name() + "_" + kOutStructNameSuffix);
auto out_var_name = generate_name(kTintStructOutVarPrefix);
auto out_struct_name = namer_->GenerateName(
namer_->NameFor(func->symbol()) + "_" + kOutStructNameSuffix);
auto out_var_name = namer_->GenerateName(kTintStructOutVarPrefix);
ep_sym_to_out_data_[func->symbol().value()] = {out_struct_name,
out_var_name};
@ -1077,7 +1068,7 @@ bool GeneratorImpl::EmitEntryPointData(ast::Function* func) {
auto* deco = data.second;
make_indent();
if (!EmitType(var->type(), var->name())) {
if (!EmitType(var->type(), var->symbol())) {
return false;
}
@ -1229,7 +1220,7 @@ bool GeneratorImpl::EmitFunctionInternal(ast::Function* func,
bool emit_duplicate_functions,
Symbol ep_sym) {
auto name = func->symbol().to_str();
if (!EmitType(func->return_type(), "")) {
if (!EmitType(func->return_type(), Symbol())) {
return false;
}
@ -1237,13 +1228,11 @@ bool GeneratorImpl::EmitFunctionInternal(ast::Function* func,
if (emit_duplicate_functions) {
auto func_name = name;
auto ep_name = ep_sym.to_str();
// TODO(dsinclair): The SymbolToName should go away and just use
// to_str() here when the conversion is complete.
name = generate_name(func->name() + "_" + module_->SymbolToName(ep_sym));
name = namer_->GenerateName(namer_->NameFor(func->symbol()) + "_" +
namer_->NameFor(ep_sym));
ep_func_name_remapped_[ep_name + "_" + func_name] = name;
} else {
// TODO(dsinclair): this should be updated to a remapped name
name = namer_.NameFor(func->name());
name = namer_->NameFor(func->symbol());
}
out_ << name << "(";
@ -1283,7 +1272,7 @@ bool GeneratorImpl::EmitFunctionInternal(ast::Function* func,
first = false;
out_ << "thread ";
if (!EmitType(var->type(), "")) {
if (!EmitType(var->type(), Symbol())) {
return false;
}
out_ << "& " << var->name();
@ -1298,7 +1287,7 @@ bool GeneratorImpl::EmitFunctionInternal(ast::Function* func,
out_ << "constant ";
// TODO(dsinclair): Can arrays be uniform? If so, fix this ...
if (!EmitType(var->type(), "")) {
if (!EmitType(var->type(), Symbol())) {
return false;
}
out_ << "& " << var->name();
@ -1321,7 +1310,7 @@ bool GeneratorImpl::EmitFunctionInternal(ast::Function* func,
}
out_ << "device ";
if (!EmitType(ac->type(), "")) {
if (!EmitType(ac->type(), Symbol())) {
return false;
}
out_ << "& " << var->name();
@ -1333,7 +1322,7 @@ bool GeneratorImpl::EmitFunctionInternal(ast::Function* func,
}
first = false;
if (!EmitType(v->type(), v->name())) {
if (!EmitType(v->type(), v->symbol())) {
return false;
}
// Array name is output as part of the type
@ -1398,7 +1387,7 @@ bool GeneratorImpl::EmitEntryPointFunction(ast::Function* func) {
} else {
out_ << "void";
}
out_ << " " << namer_.NameFor(func->name()) << "(";
out_ << " " << namer_->NameFor(func->symbol()) << "(";
bool first = true;
auto in_data = ep_sym_to_in_data_.find(current_ep_sym_.value());
@ -1421,7 +1410,7 @@ bool GeneratorImpl::EmitEntryPointFunction(ast::Function* func) {
auto* builtin = data.second;
if (!EmitType(var->type(), "")) {
if (!EmitType(var->type(), Symbol())) {
return false;
}
@ -1453,7 +1442,7 @@ bool GeneratorImpl::EmitEntryPointFunction(ast::Function* func) {
out_ << "constant ";
// TODO(dsinclair): Can you have a uniform array? If so, this needs to be
// updated to handle arrays property.
if (!EmitType(var->type(), "")) {
if (!EmitType(var->type(), Symbol())) {
return false;
}
out_ << "& " << var->name() << " [[buffer(" << binding->value() << ")]]";
@ -1482,7 +1471,7 @@ bool GeneratorImpl::EmitEntryPointFunction(ast::Function* func) {
}
out_ << "device ";
if (!EmitType(ac->type(), "")) {
if (!EmitType(ac->type(), Symbol())) {
return false;
}
out_ << "& " << var->name() << " [[buffer(" << binding->value() << ")]]";
@ -1541,7 +1530,7 @@ bool GeneratorImpl::EmitIdentifier(ast::IdentifierExpression* expr) {
out_ << name << ".";
}
}
out_ << namer_.NameFor(ident->name());
out_ << namer_->NameFor(ident->symbol());
return true;
}
@ -1549,8 +1538,8 @@ bool GeneratorImpl::EmitIdentifier(ast::IdentifierExpression* expr) {
bool GeneratorImpl::EmitLoop(ast::LoopStatement* stmt) {
loop_emission_counter_++;
std::string guard = namer_.NameFor("tint_msl_is_first_" +
std::to_string(loop_emission_counter_));
std::string guard = namer_->GenerateName(
"tint_msl_is_first_" + std::to_string(loop_emission_counter_));
if (stmt->has_continuing()) {
make_indent();
@ -1815,9 +1804,9 @@ bool GeneratorImpl::EmitSwitch(ast::SwitchStatement* stmt) {
return true;
}
bool GeneratorImpl::EmitType(ast::type::Type* type, const std::string& name) {
bool GeneratorImpl::EmitType(ast::type::Type* type, const Symbol& symbol) {
if (auto* alias = type->As<ast::type::Alias>()) {
out_ << namer_.NameFor(alias->name());
out_ << namer_->NameFor(alias->symbol());
} else if (auto* ary = type->As<ast::type::Array>()) {
ast::type::Type* base_type = ary;
std::vector<uint32_t> sizes;
@ -1829,11 +1818,11 @@ bool GeneratorImpl::EmitType(ast::type::Type* type, const std::string& name) {
}
base_type = arr->type();
}
if (!EmitType(base_type, "")) {
if (!EmitType(base_type, Symbol())) {
return false;
}
if (!name.empty()) {
out_ << " " << namer_.NameFor(name);
if (symbol.IsValid()) {
out_ << " " << namer_->NameFor(symbol);
}
for (uint32_t size : sizes) {
out_ << "[" << size << "]";
@ -1845,13 +1834,13 @@ bool GeneratorImpl::EmitType(ast::type::Type* type, const std::string& name) {
} else if (type->Is<ast::type::I32>()) {
out_ << "int";
} else if (auto* mat = type->As<ast::type::Matrix>()) {
if (!EmitType(mat->type(), "")) {
if (!EmitType(mat->type(), Symbol())) {
return false;
}
out_ << mat->columns() << "x" << mat->rows();
} else if (auto* ptr = type->As<ast::type::Pointer>()) {
// TODO(dsinclair): Storage class?
if (!EmitType(ptr->type(), "")) {
if (!EmitType(ptr->type(), Symbol())) {
return false;
}
out_ << "*";
@ -1901,7 +1890,7 @@ bool GeneratorImpl::EmitType(ast::type::Type* type, const std::string& name) {
if (tex->Is<ast::type::DepthTexture>()) {
out_ << "float, access::sample";
} else if (auto* storage = tex->As<ast::type::StorageTexture>()) {
if (!EmitType(storage->type(), "")) {
if (!EmitType(storage->type(), Symbol())) {
return false;
}
out_ << ", access::";
@ -1914,12 +1903,12 @@ bool GeneratorImpl::EmitType(ast::type::Type* type, const std::string& name) {
return false;
}
} else if (auto* ms = tex->As<ast::type::MultisampledTexture>()) {
if (!EmitType(ms->type(), "")) {
if (!EmitType(ms->type(), Symbol())) {
return false;
}
out_ << ", access::sample";
} else if (auto* sampled = tex->As<ast::type::SampledTexture>()) {
if (!EmitType(sampled->type(), "")) {
if (!EmitType(sampled->type(), Symbol())) {
return false;
}
out_ << ", access::sample";
@ -1932,7 +1921,7 @@ bool GeneratorImpl::EmitType(ast::type::Type* type, const std::string& name) {
} else if (type->Is<ast::type::U32>()) {
out_ << "uint";
} else if (auto* vec = type->As<ast::type::Vector>()) {
if (!EmitType(vec->type(), "")) {
if (!EmitType(vec->type(), Symbol())) {
return false;
}
out_ << vec->size();
@ -1973,7 +1962,7 @@ bool GeneratorImpl::EmitStructType(const ast::type::Struct* str) {
}
}
if (!EmitType(mem->type(), mem->name())) {
if (!EmitType(mem->type(), mem->symbol())) {
return false;
}
auto size = calculate_alignment_size(mem->type());
@ -1985,7 +1974,7 @@ bool GeneratorImpl::EmitStructType(const ast::type::Struct* str) {
// Array member name will be output with the type
if (!mem->type()->Is<ast::type::Array>()) {
out_ << " " << namer_.NameFor(mem->name());
out_ << " " << namer_->NameFor(mem->symbol());
}
out_ << ";" << std::endl;
}
@ -2027,7 +2016,7 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var, bool skip_constructor) {
if (var->is_const()) {
out_ << "const ";
}
if (!EmitType(var->type(), var->name())) {
if (!EmitType(var->type(), var->symbol())) {
return false;
}
if (!var->type()->Is<ast::type::Array>()) {
@ -2069,7 +2058,7 @@ bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
}
out_ << "constant ";
if (!EmitType(var->type(), var->name())) {
if (!EmitType(var->type(), var->symbol())) {
return false;
}
if (!var->type()->Is<ast::type::Array>()) {

View File

@ -15,6 +15,7 @@
#ifndef SRC_WRITER_MSL_GENERATOR_IMPL_H_
#define SRC_WRITER_MSL_GENERATOR_IMPL_H_
#include <memory>
#include <sstream>
#include <string>
#include <unordered_map>
@ -42,8 +43,8 @@
#include "src/ast/type/struct_type.h"
#include "src/ast/type_constructor_expression.h"
#include "src/ast/unary_op_expression.h"
#include "src/namer.h"
#include "src/scope_stack.h"
#include "src/writer/msl/namer.h"
#include "src/writer/text_generator.h"
namespace tint {
@ -202,9 +203,9 @@ class GeneratorImpl : public TextGenerator {
bool EmitSwitch(ast::SwitchStatement* stmt);
/// Handles generating type
/// @param type the type to generate
/// @param name the name of the variable, only used for array emission
/// @param symbol the symbol of the variable, only used for array emission
/// @returns true if the type is emitted
bool EmitType(ast::type::Type* type, const std::string& name);
bool EmitType(ast::type::Type* type, const Symbol& symbol);
/// Handles generating a struct declaration
/// @param str the struct to generate
/// @returns true if the struct is emitted
@ -244,10 +245,6 @@ class GeneratorImpl : public TextGenerator {
/// @returns true if an input or output struct is required.
bool has_referenced_var_needing_struct(ast::Function* func);
/// Generates a name for the prefix
/// @param prefix the prefix of the name to generate
/// @returns the name
std::string generate_name(const std::string& prefix);
/// Generates an intrinsic name from the given name
/// @param intrinsic the intrinsic to convert to an method name
/// @returns the intrinsic name or blank on error
@ -268,7 +265,7 @@ class GeneratorImpl : public TextGenerator {
std::string builtin_to_attribute(ast::Builtin builtin) const;
/// @returns the namer for testing purposes
Namer* namer_for_testing() { return &namer_; }
Namer* namer_for_testing() { return namer_.get(); }
private:
enum class VarType { kIn, kOut };
@ -280,12 +277,12 @@ class GeneratorImpl : public TextGenerator {
std::string current_ep_var_name(VarType type);
Namer namer_;
ScopeStack<ast::Variable*> global_variables_;
Symbol current_ep_sym_;
bool generating_entry_point_ = false;
const ast::Module* module_ = nullptr;
uint32_t loop_emission_counter_ = 0;
std::unique_ptr<Namer> namer_;
std::unordered_map<uint32_t, EntryPointData> ep_sym_to_in_data_;
std::unordered_map<uint32_t, EntryPointData> ep_sym_to_out_data_;

View File

@ -35,14 +35,6 @@ TEST_F(MslGeneratorImplTest, EmitConstructedType_F32) {
)");
}
TEST_F(MslGeneratorImplTest, EmitConstructedType_NameCollision) {
auto* alias = ty.alias("float", ty.f32);
ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
EXPECT_EQ(gen.result(), R"(typedef float float_tint_0;
)");
}
TEST_F(MslGeneratorImplTest, EmitConstructedType_Struct) {
auto* str = create<ast::Struct>(
ast::StructMemberList{Member("a", ty.f32),

View File

@ -88,7 +88,7 @@ TEST_F(MslGeneratorImplTest, Emit_Function_Name_Collision) {
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
void main_tint_0() {
void main() {
return;
}
@ -797,25 +797,6 @@ fragment ep_1_out ep_1() {
)");
}
TEST_F(MslGeneratorImplTest,
Emit_FunctionDecoration_EntryPoint_WithNameCollision) {
auto* func =
Func("main", ast::VariableList{}, ty.void_, ast::StatementList{},
ast::FunctionDecorationList{
create<ast::StageDecoration>(ast::PipelineStage::kCompute),
});
mod->AddFunction(func);
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
kernel void main_tint_0() {
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_Function_WithArrayParams) {
ast::VariableList params;
params.push_back(Var("a", ast::StorageClass::kNone, ty.array<f32, 5>()));

View File

@ -34,7 +34,7 @@ TEST_F(MslGeneratorImplTest, EmitIdentifierExpression) {
TEST_F(MslGeneratorImplTest, EmitIdentifierExpression_Single_WithCollision) {
auto* i = Expr("virtual");
ASSERT_TRUE(gen.EmitExpression(i)) << gen.error();
EXPECT_EQ(gen.result(), "virtual_tint_0");
EXPECT_EQ(gen.result(), "virtual");
}
} // namespace

View File

@ -33,181 +33,181 @@ std::string expected_texture_overload(
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
switch (overload) {
case ValidTextureOverload::kSample1dF32:
return R"(texture_tint_0.sample(sampler_tint_0, 1.0f))";
return R"(texture.sample(sampler, 1.0f))";
case ValidTextureOverload::kSample1dArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, 1.0f, 2))";
return R"(texture.sample(sampler, 1.0f, 2))";
case ValidTextureOverload::kSample2dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f)))";
case ValidTextureOverload::kSample2dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), int2(3, 4)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), int2(3, 4)))";
case ValidTextureOverload::kSample2dArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3))";
case ValidTextureOverload::kSample2dArrayOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3, int2(4, 5)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3, int2(4, 5)))";
case ValidTextureOverload::kSample3dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f)))";
case ValidTextureOverload::kSample3dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), int3(4, 5, 6)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), int3(4, 5, 6)))";
case ValidTextureOverload::kSampleCubeF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f)))";
case ValidTextureOverload::kSampleCubeArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), 4))";
case ValidTextureOverload::kSampleDepth2dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f)))";
case ValidTextureOverload::kSampleDepth2dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), int2(3, 4)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), int2(3, 4)))";
case ValidTextureOverload::kSampleDepth2dArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3))";
case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3, int2(4, 5)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3, int2(4, 5)))";
case ValidTextureOverload::kSampleDepthCubeF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f)))";
case ValidTextureOverload::kSampleDepthCubeArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), 4))";
case ValidTextureOverload::kSampleBias2dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), bias(3.0f)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), bias(3.0f)))";
case ValidTextureOverload::kSampleBias2dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), bias(3.0f), int2(4, 5)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), bias(3.0f), int2(4, 5)))";
case ValidTextureOverload::kSampleBias2dArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 4, bias(3.0f)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 4, bias(3.0f)))";
case ValidTextureOverload::kSampleBias2dArrayOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3, bias(4.0f), int2(5, 6)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3, bias(4.0f), int2(5, 6)))";
case ValidTextureOverload::kSampleBias3dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), bias(4.0f)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), bias(4.0f)))";
case ValidTextureOverload::kSampleBias3dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), bias(4.0f), int3(5, 6, 7)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), bias(4.0f), int3(5, 6, 7)))";
case ValidTextureOverload::kSampleBiasCubeF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), bias(4.0f)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), bias(4.0f)))";
case ValidTextureOverload::kSampleBiasCubeArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 3, bias(4.0f)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), 3, bias(4.0f)))";
case ValidTextureOverload::kSampleLevel2dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), level(3.0f)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), level(3.0f)))";
case ValidTextureOverload::kSampleLevel2dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), level(3.0f), int2(4, 5)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), level(3.0f), int2(4, 5)))";
case ValidTextureOverload::kSampleLevel2dArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3, level(4.0f)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3, level(4.0f)))";
case ValidTextureOverload::kSampleLevel2dArrayOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3, level(4.0f), int2(5, 6)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3, level(4.0f), int2(5, 6)))";
case ValidTextureOverload::kSampleLevel3dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), level(4.0f)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), level(4.0f)))";
case ValidTextureOverload::kSampleLevel3dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), level(4.0f), int3(5, 6, 7)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), level(4.0f), int3(5, 6, 7)))";
case ValidTextureOverload::kSampleLevelCubeF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), level(4.0f)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), level(4.0f)))";
case ValidTextureOverload::kSampleLevelCubeArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4, level(5.0f)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), 4, level(5.0f)))";
case ValidTextureOverload::kSampleLevelDepth2dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), level(3)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), level(3)))";
case ValidTextureOverload::kSampleLevelDepth2dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), level(3), int2(4, 5)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), level(3), int2(4, 5)))";
case ValidTextureOverload::kSampleLevelDepth2dArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3, level(4)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3, level(4)))";
case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3, level(4), int2(5, 6)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3, level(4), int2(5, 6)))";
case ValidTextureOverload::kSampleLevelDepthCubeF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), level(4)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), level(4)))";
case ValidTextureOverload::kSampleLevelDepthCubeArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4, level(5)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), 4, level(5)))";
case ValidTextureOverload::kSampleGrad2dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), gradient2d(float2(3.0f, 4.0f), float2(5.0f, 6.0f))))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), gradient2d(float2(3.0f, 4.0f), float2(5.0f, 6.0f))))";
case ValidTextureOverload::kSampleGrad2dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), gradient2d(float2(3.0f, 4.0f), float2(5.0f, 6.0f)), int2(7, 8)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), gradient2d(float2(3.0f, 4.0f), float2(5.0f, 6.0f)), int2(7, 8)))";
case ValidTextureOverload::kSampleGrad2dArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3, gradient2d(float2(4.0f, 5.0f), float2(6.0f, 7.0f))))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3, gradient2d(float2(4.0f, 5.0f), float2(6.0f, 7.0f))))";
case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float2(1.0f, 2.0f), 3, gradient2d(float2(4.0f, 5.0f), float2(6.0f, 7.0f)), int2(8, 9)))";
return R"(texture.sample(sampler, float2(1.0f, 2.0f), 3, gradient2d(float2(4.0f, 5.0f), float2(6.0f, 7.0f)), int2(8, 9)))";
case ValidTextureOverload::kSampleGrad3dF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), gradient3d(float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), gradient3d(float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))))";
case ValidTextureOverload::kSampleGrad3dOffsetF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), gradient3d(float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f)), int3(10, 11, 12)))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), gradient3d(float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f)), int3(10, 11, 12)))";
case ValidTextureOverload::kSampleGradCubeF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), gradientcube(float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), gradientcube(float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))))";
case ValidTextureOverload::kSampleGradCubeArrayF32:
return R"(texture_tint_0.sample(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4, gradientcube(float3(5.0f, 6.0f, 7.0f), float3(8.0f, 9.0f, 10.0f))))";
return R"(texture.sample(sampler, float3(1.0f, 2.0f, 3.0f), 4, gradientcube(float3(5.0f, 6.0f, 7.0f), float3(8.0f, 9.0f, 10.0f))))";
case ValidTextureOverload::kSampleGradDepth2dF32:
return R"(texture_tint_0.sample_compare(sampler_tint_0, float2(1.0f, 2.0f), 3.0f))";
return R"(texture.sample_compare(sampler, float2(1.0f, 2.0f), 3.0f))";
case ValidTextureOverload::kSampleGradDepth2dOffsetF32:
return R"(texture_tint_0.sample_compare(sampler_tint_0, float2(1.0f, 2.0f), 3.0f, int2(4, 5)))";
return R"(texture.sample_compare(sampler, float2(1.0f, 2.0f), 3.0f, int2(4, 5)))";
case ValidTextureOverload::kSampleGradDepth2dArrayF32:
return R"(texture_tint_0.sample_compare(sampler_tint_0, float2(1.0f, 2.0f), 4, 3.0f))";
return R"(texture.sample_compare(sampler, float2(1.0f, 2.0f), 4, 3.0f))";
case ValidTextureOverload::kSampleGradDepth2dArrayOffsetF32:
return R"(texture_tint_0.sample_compare(sampler_tint_0, float2(1.0f, 2.0f), 4, 3.0f, int2(5, 6)))";
return R"(texture.sample_compare(sampler, float2(1.0f, 2.0f), 4, 3.0f, int2(5, 6)))";
case ValidTextureOverload::kSampleGradDepthCubeF32:
return R"(texture_tint_0.sample_compare(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4.0f))";
return R"(texture.sample_compare(sampler, float3(1.0f, 2.0f, 3.0f), 4.0f))";
case ValidTextureOverload::kSampleGradDepthCubeArrayF32:
return R"(texture_tint_0.sample_compare(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4, 5.0f))";
return R"(texture.sample_compare(sampler, float3(1.0f, 2.0f, 3.0f), 4, 5.0f))";
case ValidTextureOverload::kLoad1dF32:
return R"(texture_tint_0.read(1))";
return R"(texture.read(1))";
case ValidTextureOverload::kLoad1dU32:
return R"(texture_tint_0.read(1))";
return R"(texture.read(1))";
case ValidTextureOverload::kLoad1dI32:
return R"(texture_tint_0.read(1))";
return R"(texture.read(1))";
case ValidTextureOverload::kLoad1dArrayF32:
return R"(texture_tint_0.read(1, 2))";
return R"(texture.read(1, 2))";
case ValidTextureOverload::kLoad1dArrayU32:
return R"(texture_tint_0.read(1, 2))";
return R"(texture.read(1, 2))";
case ValidTextureOverload::kLoad1dArrayI32:
return R"(texture_tint_0.read(1, 2))";
return R"(texture.read(1, 2))";
case ValidTextureOverload::kLoad2dF32:
return R"(texture_tint_0.read(int2(1, 2)))";
return R"(texture.read(int2(1, 2)))";
case ValidTextureOverload::kLoad2dU32:
return R"(texture_tint_0.read(int2(1, 2)))";
return R"(texture.read(int2(1, 2)))";
case ValidTextureOverload::kLoad2dI32:
return R"(texture_tint_0.read(int2(1, 2)))";
return R"(texture.read(int2(1, 2)))";
case ValidTextureOverload::kLoad2dLevelF32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoad2dLevelU32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoad2dLevelI32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoad2dArrayF32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoad2dArrayU32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoad2dArrayI32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoad2dArrayLevelF32:
return R"(texture_tint_0.read(int2(1, 2), 3, 4))";
return R"(texture.read(int2(1, 2), 3, 4))";
case ValidTextureOverload::kLoad2dArrayLevelU32:
return R"(texture_tint_0.read(int2(1, 2), 3, 4))";
return R"(texture.read(int2(1, 2), 3, 4))";
case ValidTextureOverload::kLoad2dArrayLevelI32:
return R"(texture_tint_0.read(int2(1, 2), 3, 4))";
return R"(texture.read(int2(1, 2), 3, 4))";
case ValidTextureOverload::kLoad3dF32:
return R"(texture_tint_0.read(int3(1, 2, 3)))";
return R"(texture.read(int3(1, 2, 3)))";
case ValidTextureOverload::kLoad3dU32:
return R"(texture_tint_0.read(int3(1, 2, 3)))";
return R"(texture.read(int3(1, 2, 3)))";
case ValidTextureOverload::kLoad3dI32:
return R"(texture_tint_0.read(int3(1, 2, 3)))";
return R"(texture.read(int3(1, 2, 3)))";
case ValidTextureOverload::kLoad3dLevelF32:
return R"(texture_tint_0.read(int3(1, 2, 3), 4))";
return R"(texture.read(int3(1, 2, 3), 4))";
case ValidTextureOverload::kLoad3dLevelU32:
return R"(texture_tint_0.read(int3(1, 2, 3), 4))";
return R"(texture.read(int3(1, 2, 3), 4))";
case ValidTextureOverload::kLoad3dLevelI32:
return R"(texture_tint_0.read(int3(1, 2, 3), 4))";
return R"(texture.read(int3(1, 2, 3), 4))";
case ValidTextureOverload::kLoadMultisampled2dF32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoadMultisampled2dU32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoadMultisampled2dI32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoadMultisampled2dArrayF32:
return R"(texture_tint_0.read(int2(1, 2), 3, 4))";
return R"(texture.read(int2(1, 2), 3, 4))";
case ValidTextureOverload::kLoadMultisampled2dArrayU32:
return R"(texture_tint_0.read(int2(1, 2), 3, 4))";
return R"(texture.read(int2(1, 2), 3, 4))";
case ValidTextureOverload::kLoadMultisampled2dArrayI32:
return R"(texture_tint_0.read(int2(1, 2), 3, 4))";
return R"(texture.read(int2(1, 2), 3, 4))";
case ValidTextureOverload::kLoadDepth2dF32:
return R"(texture_tint_0.read(int2(1, 2)))";
return R"(texture.read(int2(1, 2)))";
case ValidTextureOverload::kLoadDepth2dLevelF32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoadDepth2dArrayF32:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoadDepth2dArrayLevelF32:
return R"(texture_tint_0.read(int2(1, 2), 3, 4))";
return R"(texture.read(int2(1, 2), 3, 4))";
case ValidTextureOverload::kLoadStorageRO1dRgba32float:
return R"(texture_tint_0.read(1))";
return R"(texture.read(1))";
case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float:
return R"(texture_tint_0.read(1, 2))";
return R"(texture.read(1, 2))";
case ValidTextureOverload::kLoadStorageRO2dRgba8unorm:
case ValidTextureOverload::kLoadStorageRO2dRgba8snorm:
case ValidTextureOverload::kLoadStorageRO2dRgba8uint:
@ -224,21 +224,21 @@ std::string expected_texture_overload(
case ValidTextureOverload::kLoadStorageRO2dRgba32uint:
case ValidTextureOverload::kLoadStorageRO2dRgba32sint:
case ValidTextureOverload::kLoadStorageRO2dRgba32float:
return R"(texture_tint_0.read(int2(1, 2)))";
return R"(texture.read(int2(1, 2)))";
case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float:
return R"(texture_tint_0.read(int2(1, 2), 3))";
return R"(texture.read(int2(1, 2), 3))";
case ValidTextureOverload::kLoadStorageRO3dRgba32float:
return R"(texture_tint_0.read(int3(1, 2, 3)))";
return R"(texture.read(int3(1, 2, 3)))";
case ValidTextureOverload::kStoreWO1dRgba32float:
return R"(texture_tint_0.write(float4(2.0f, 3.0f, 4.0f, 5.0f), 1))";
return R"(texture.write(float4(2.0f, 3.0f, 4.0f, 5.0f), 1))";
case ValidTextureOverload::kStoreWO1dArrayRgba32float:
return R"(texture_tint_0.write(float4(3.0f, 4.0f, 5.0f, 6.0f), 1, 2))";
return R"(texture.write(float4(3.0f, 4.0f, 5.0f, 6.0f), 1, 2))";
case ValidTextureOverload::kStoreWO2dRgba32float:
return R"(texture_tint_0.write(float4(3.0f, 4.0f, 5.0f, 6.0f), int2(1, 2)))";
return R"(texture.write(float4(3.0f, 4.0f, 5.0f, 6.0f), int2(1, 2)))";
case ValidTextureOverload::kStoreWO2dArrayRgba32float:
return R"(texture_tint_0.write(float4(4.0f, 5.0f, 6.0f, 7.0f), int2(1, 2), 3))";
return R"(texture.write(float4(4.0f, 5.0f, 6.0f, 7.0f), int2(1, 2), 3))";
case ValidTextureOverload::kStoreWO3dRgba32float:
return R"(texture_tint_0.write(float4(4.0f, 5.0f, 6.0f, 7.0f), int3(1, 2, 3)))";
return R"(texture.write(float4(4.0f, 5.0f, 6.0f, 7.0f), int3(1, 2, 3)))";
}
return "<unmatched texture overload>";
} // NOLINT - Ignore the length of this function

View File

@ -37,7 +37,6 @@
#include "src/ast/type/u32_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/type/void_type.h"
#include "src/writer/msl/namer.h"
#include "src/writer/msl/test_helper.h"
namespace tint {
@ -64,21 +63,6 @@ kernel void my_func() {
)");
}
TEST_F(MslGeneratorImplTest, InputStructName) {
ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in");
}
TEST_F(MslGeneratorImplTest, InputStructName_ConflictWithExisting) {
gen.namer_for_testing()->NameFor("func_main_out");
ASSERT_EQ(gen.generate_name("func_main_out"), "func_main_out_0");
}
TEST_F(MslGeneratorImplTest, NameConflictWith_InputStructName) {
ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in");
ASSERT_TRUE(gen.EmitIdentifier(Expr("func_main_in")));
EXPECT_EQ(gen.result(), "func_main_in_0");
}
struct MslBuiltinData {
ast::Builtin builtin;
const char* attribute_name;

View File

@ -48,25 +48,21 @@ using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitType_Alias) {
auto* alias = ty.alias("alias", ty.f32);
ASSERT_TRUE(gen.EmitType(alias, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(alias, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "alias");
}
TEST_F(MslGeneratorImplTest, EmitType_Alias_NameCollision) {
auto* alias = ty.alias("bool", ty.f32);
ASSERT_TRUE(gen.EmitType(alias, "")) << gen.error();
EXPECT_EQ(gen.result(), "bool_tint_0");
}
TEST_F(MslGeneratorImplTest, EmitType_Array) {
ASSERT_TRUE(gen.EmitType(ty.array<bool, 4>(), "ary")) << gen.error();
auto sym = mod->RegisterSymbol("ary");
ASSERT_TRUE(gen.EmitType(ty.array<bool, 4>(), sym)) << gen.error();
EXPECT_EQ(gen.result(), "bool ary[4]");
}
TEST_F(MslGeneratorImplTest, EmitType_ArrayOfArray) {
auto* a = ty.array<bool, 4>();
auto* b = ty.array(a, 5);
ASSERT_TRUE(gen.EmitType(b, "ary")) << gen.error();
auto sym = mod->RegisterSymbol("ary");
ASSERT_TRUE(gen.EmitType(b, sym)) << gen.error();
EXPECT_EQ(gen.result(), "bool ary[5][4]");
}
@ -75,7 +71,8 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_ArrayOfArrayOfRuntimeArray) {
auto* a = ty.array<bool, 4>();
auto* b = ty.array(a, 5);
auto* c = ty.array(b, 0);
ASSERT_TRUE(gen.EmitType(c, "ary")) << gen.error();
auto sym = mod->RegisterSymbol("ary");
ASSERT_TRUE(gen.EmitType(c, sym)) << gen.error();
EXPECT_EQ(gen.result(), "bool ary[5][4][1]");
}
@ -83,48 +80,39 @@ TEST_F(MslGeneratorImplTest, EmitType_ArrayOfArrayOfArray) {
auto* a = ty.array<bool, 4>();
auto* b = ty.array(a, 5);
auto* c = ty.array(b, 6);
ASSERT_TRUE(gen.EmitType(c, "ary")) << gen.error();
auto sym = mod->RegisterSymbol("ary");
ASSERT_TRUE(gen.EmitType(c, sym)) << gen.error();
EXPECT_EQ(gen.result(), "bool ary[6][5][4]");
}
TEST_F(MslGeneratorImplTest, EmitType_Array_NameCollision) {
ASSERT_TRUE(gen.EmitType(ty.array<bool, 4>(), "bool")) << gen.error();
EXPECT_EQ(gen.result(), "bool bool_tint_0[4]");
}
TEST_F(MslGeneratorImplTest, EmitType_Array_WithoutName) {
ASSERT_TRUE(gen.EmitType(ty.array<bool, 4>(), "")) << gen.error();
ASSERT_TRUE(gen.EmitType(ty.array<bool, 4>(), Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "bool[4]");
}
TEST_F(MslGeneratorImplTest, EmitType_RuntimeArray) {
ASSERT_TRUE(gen.EmitType(ty.array<bool, 1>(), "ary")) << gen.error();
auto sym = mod->RegisterSymbol("ary");
ASSERT_TRUE(gen.EmitType(ty.array<bool, 1>(), sym)) << gen.error();
EXPECT_EQ(gen.result(), "bool ary[1]");
}
TEST_F(MslGeneratorImplTest, EmitType_RuntimeArray_NameCollision) {
ASSERT_TRUE(gen.EmitType(ty.array<bool, 1>(), "discard_fragment"))
<< gen.error();
EXPECT_EQ(gen.result(), "bool discard_fragment_tint_0[1]");
}
TEST_F(MslGeneratorImplTest, EmitType_Bool) {
ASSERT_TRUE(gen.EmitType(ty.bool_, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(ty.bool_, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "bool");
}
TEST_F(MslGeneratorImplTest, EmitType_F32) {
ASSERT_TRUE(gen.EmitType(ty.f32, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(ty.f32, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "float");
}
TEST_F(MslGeneratorImplTest, EmitType_I32) {
ASSERT_TRUE(gen.EmitType(ty.i32, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(ty.i32, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "int");
}
TEST_F(MslGeneratorImplTest, EmitType_Matrix) {
ASSERT_TRUE(gen.EmitType(ty.mat2x3<f32>(), "")) << gen.error();
ASSERT_TRUE(gen.EmitType(ty.mat2x3<f32>(), Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "float2x3");
}
@ -132,7 +120,7 @@ TEST_F(MslGeneratorImplTest, EmitType_Matrix) {
TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Pointer) {
ast::type::Pointer p(ty.f32, ast::StorageClass::kWorkgroup);
ASSERT_TRUE(gen.EmitType(&p, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&p, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "float*");
}
@ -143,7 +131,7 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct) {
ast::StructDecorationList{});
auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitType(s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(s, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "S");
}
@ -185,20 +173,6 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_InjectPadding) {
)");
}
TEST_F(MslGeneratorImplTest, EmitType_Struct_NameCollision) {
auto* str = create<ast::Struct>(
ast::StructMemberList{Member("main", ty.i32), Member("float", ty.f32)},
ast::StructDecorationList{});
auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
EXPECT_EQ(gen.result(), R"(struct S {
int main_tint_0;
float float_tint_0;
};
)");
}
// TODO(dsinclair): How to translate [[block]]
TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) {
ast::StructDecorationList decos;
@ -209,7 +183,7 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) {
decos);
auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitType(s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(s, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), R"(struct {
int a;
float b;
@ -217,31 +191,31 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) {
}
TEST_F(MslGeneratorImplTest, EmitType_U32) {
ASSERT_TRUE(gen.EmitType(ty.u32, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(ty.u32, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "uint");
}
TEST_F(MslGeneratorImplTest, EmitType_Vector) {
ASSERT_TRUE(gen.EmitType(ty.vec3<f32>(), "")) << gen.error();
ASSERT_TRUE(gen.EmitType(ty.vec3<f32>(), Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "float3");
}
TEST_F(MslGeneratorImplTest, EmitType_Void) {
ASSERT_TRUE(gen.EmitType(ty.void_, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(ty.void_, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "void");
}
TEST_F(MslGeneratorImplTest, EmitType_Sampler) {
ast::type::Sampler sampler(ast::type::SamplerKind::kSampler);
ASSERT_TRUE(gen.EmitType(&sampler, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&sampler, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "sampler");
}
TEST_F(MslGeneratorImplTest, EmitType_SamplerComparison) {
ast::type::Sampler sampler(ast::type::SamplerKind::kComparisonSampler);
ASSERT_TRUE(gen.EmitType(&sampler, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&sampler, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "sampler");
}
@ -259,7 +233,7 @@ TEST_P(MslDepthTexturesTest, Emit) {
ast::type::DepthTexture s(params.dim);
ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&s, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), params.result);
}
INSTANTIATE_TEST_SUITE_P(
@ -289,7 +263,7 @@ TEST_P(MslSampledtexturesTest, Emit) {
ast::type::SampledTexture s(params.dim, ty.f32);
ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&s, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), params.result);
}
INSTANTIATE_TEST_SUITE_P(
@ -314,7 +288,7 @@ INSTANTIATE_TEST_SUITE_P(
TEST_F(MslGeneratorImplTest, Emit_TypeMultisampledTexture) {
ast::type::MultisampledTexture s(ast::type::TextureDimension::k2d, ty.u32);
ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&s, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), "texture2d_ms<uint, access::sample>");
}
@ -337,7 +311,7 @@ TEST_P(MslStorageTexturesTest, Emit) {
ast::type::ImageFormat::kR16Float);
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&s, Symbol())) << gen.error();
EXPECT_EQ(gen.result(), params.result);
}
INSTANTIATE_TEST_SUITE_P(

View File

@ -1,323 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/writer/msl/namer.h"
#include <algorithm>
namespace tint {
namespace writer {
namespace msl {
namespace {
const char* kNames[] = {"access",
"alignas",
"alignof",
"and",
"and_eq",
"array",
"array_ref",
"as_type",
"asm",
"atomic",
"atomic_bool",
"atomic_int",
"atomic_uint",
"auto",
"bitand",
"bitor",
"bool",
"bool2",
"bool3",
"bool4",
"break",
"buffer",
"case",
"catch",
"char",
"char16_t",
"char2",
"char3",
"char32_t",
"char4",
"class",
"compl",
"const",
"const_cast",
"const_reference",
"constant",
"constexpr",
"continue",
"decltype",
"default",
"delete",
"depth2d",
"depth2d_array",
"depth2d_ms",
"depth2d_ms_array",
"depthcube",
"depthcube_array",
"device",
"discard_fragment",
"do",
"double",
"dynamic_cast",
"else",
"enum",
"explicit",
"extern",
"extern",
"false",
"final",
"float",
"float2",
"float2x2",
"float2x3",
"float2x4",
"float3",
"float3x2",
"float3x3",
"float3x4",
"float4",
"float4x2",
"float4x3",
"float4x4",
"for",
"fragment",
"friend",
"goto",
"half",
"half2",
"half2x2",
"half2x3",
"half2x4",
"half3",
"half3x2",
"half3x3",
"half3x4",
"half4",
"half4x2",
"half4x3",
"half4x4",
"if",
"imageblock",
"inline",
"inline",
"int",
"int16_t",
"int2",
"int3",
"int32_t",
"int4",
"int64_t",
"int8_t",
"kernel",
"long",
"long2",
"long3",
"long4",
"main",
"metal",
"mutable"
"mutable",
"namespace",
"new",
"noexcept"
"not",
"not_eq",
"nullptr",
"operator",
"or",
"or_eq",
"override",
"packed_bool2",
"packed_bool3",
"packed_bool4",
"packed_char2",
"packed_char3",
"packed_char4",
"packed_float2",
"packed_float3",
"packed_float4",
"packed_half2",
"packed_half3",
"packed_half4",
"packed_int2",
"packed_int3",
"packed_int4",
"packed_short2",
"packed_short3",
"packed_short4",
"packed_uchar2",
"packed_uchar3",
"packed_uchar4",
"packed_uint2",
"packed_uint3",
"packed_uint4",
"packed_ushort2",
"packed_ushort3",
"packed_ushort4",
"patch_control_point",
"private",
"protected",
"ptrdiff_t",
"public",
"r16snorm",
"r16unorm",
"r8unorm",
"reference",
"register",
"reinterpret_cast",
"return",
"rg11b10f",
"rg16snorm",
"rg16unorm",
"rg8snorm",
"rg8unorm",
"rgb10a2",
"rgb9e5",
"rgba16snorm",
"rgba16unorm",
"rgba8snorm",
"rgba8unorm",
"sampler",
"short",
"short2",
"short3",
"short4",
"signed",
"size_t",
"sizeof",
"srgba8unorm",
"static",
"static_assert",
"static_cast",
"struct",
"switch",
"template",
"texture",
"texture1d",
"texture1d_array",
"texture2d",
"texture2d_array",
"texture2d_ms",
"texture2d_ms_array",
"texture3d",
"texture_buffer",
"texturecube",
"texturecube_array",
"this",
"thread",
"thread_local",
"threadgroup",
"threadgroup_imageblock",
"throw",
"true",
"try",
"typedef",
"typeid",
"typename",
"uchar",
"uchar2",
"uchar3",
"uchar4",
"uint",
"uint16_t",
"uint2",
"uint3",
"uint32_t",
"uint4",
"uint64_t",
"uint8_t",
"ulong2",
"ulong3",
"ulong4",
"uniform",
"union",
"unsigned",
"ushort",
"ushort2",
"ushort3",
"ushort4",
"using",
"vec",
"vertex",
"virtual",
"virtual",
"void",
"volatile",
"wchar_t",
"while",
"xor",
"xor_eq"};
} // namespace
Namer::Namer() = default;
Namer::~Namer() = default;
std::string Namer::NameFor(const std::string& name) {
// If it's in the name map we can just return it. There are no shadow names
// in WGSL so this has to be unique in the WGSL names, and we've already
// checked the name collisions with MSL.
auto it = name_map_.find(name);
if (it != name_map_.end()) {
return it->second;
}
std::string ret_name = name;
if (std::binary_search(std::begin(kNames), std::end(kNames), ret_name)) {
uint32_t i = 0;
// Make sure there wasn't already a tint variable with the new name we've
// now created.
while (true) {
ret_name = name + "_tint_" + std::to_string(i);
it = name_map_.find(ret_name);
if (it == name_map_.end()) {
break;
}
i++;
}
RegisterRemappedName(ret_name);
} else {
uint32_t i = 0;
// Make sure the ident name wasn't assigned by a remapping.
while (true) {
auto remap_it = remapped_names_.find(ret_name);
if (remap_it == remapped_names_.end()) {
break;
}
ret_name = name + "_" + std::to_string(i);
i++;
}
RegisterRemappedName(ret_name);
}
name_map_[name] = ret_name;
return ret_name;
}
bool Namer::IsMapped(const std::string& name) {
auto it = name_map_.find(name);
return it != name_map_.end();
}
void Namer::RegisterRemappedName(const std::string& name) {
remapped_names_.insert(name);
}
} // namespace msl
} // namespace writer
} // namespace tint

View File

@ -1,58 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_WRITER_MSL_NAMER_H_
#define SRC_WRITER_MSL_NAMER_H_
#include <string>
#include <unordered_map>
#include <unordered_set>
namespace tint {
namespace writer {
namespace msl {
/// Remaps maps names to avoid reserved words and collisions for MSL.
class Namer {
public:
/// Constructor
Namer();
~Namer();
/// Returns a sanitized version of `name`
/// @param name the name to sanitize
/// @returns the sanitized version of `name`
std::string NameFor(const std::string& name);
/// Registers a remapped name.
/// @param name the name to register
void RegisterRemappedName(const std::string& name);
/// Returns if the given name has been mapped alread
/// @param name the name to check
/// @returns true if the name has been mapped
bool IsMapped(const std::string& name);
private:
/// Map of original name to new name. The two names may be the same.
std::unordered_map<std::string, std::string> name_map_;
// The list of names taken by the remapper
std::unordered_set<std::string> remapped_names_;
};
} // namespace msl
} // namespace writer
} // namespace tint
#endif // SRC_WRITER_MSL_NAMER_H_

View File

@ -1,304 +0,0 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/writer/msl/namer.h"
#include "gtest/gtest.h"
namespace tint {
namespace writer {
namespace msl {
namespace {
using MslNamerTest = testing::Test;
TEST_F(MslNamerTest, ReturnsName) {
Namer n;
EXPECT_EQ("my_name", n.NameFor("my_name"));
EXPECT_EQ("my_name", n.NameFor("my_name"));
}
TEST_F(MslNamerTest, HandlesConflictWithRenamedReservedWordAfterIdentSeen) {
Namer n;
EXPECT_EQ("float_tint_0", n.NameFor("float_tint_0"));
EXPECT_EQ("float_tint_1", n.NameFor("float"));
EXPECT_EQ("float_tint_0", n.NameFor("float_tint_0"));
}
TEST_F(MslNamerTest, HandlesConflictWithRenamedReservedWordBeforeIdentSeen) {
Namer n;
EXPECT_EQ("float_tint_0", n.NameFor("float"));
EXPECT_EQ("float_tint_0_0", n.NameFor("float_tint_0"));
EXPECT_EQ("float_tint_0_0_0", n.NameFor("float_tint_0_0"));
EXPECT_EQ("float_tint_0_0", n.NameFor("float_tint_0"));
}
using MslReservedNameTest = testing::TestWithParam<std::string>;
TEST_P(MslReservedNameTest, Emit) {
auto name = GetParam();
Namer n;
EXPECT_EQ(name + "_tint_0", n.NameFor(name));
}
INSTANTIATE_TEST_SUITE_P(MslNamerTest,
MslReservedNameTest,
testing::Values(
// c++14 spec
"alignas",
"alignof",
"and",
"and_eq",
"asm",
"auto",
"bitand",
"bitor",
"bool",
"break",
"case",
"catch",
"char",
"char16_t",
"char32_t",
"class",
"compl",
"const",
"const_cast",
"constexpr",
"continue",
"decltype",
"default",
"delete",
"do",
"double",
"dynamic_cast",
"else",
"enum",
"explicit",
"extern",
"extern",
"false",
"final",
"float",
"for",
"friend",
"goto",
"if",
"inline",
"inline",
"int",
"long",
"mutable"
"mutable",
"namespace",
"new",
"noexcept"
"not",
"not_eq",
"nullptr",
"operator",
"or",
"or_eq",
"override",
"private",
"protected",
"public",
"register",
"reinterpret_cast",
"return",
"short",
"signed",
"sizeof",
"static",
"static_assert",
"static_cast",
"struct",
"switch",
"template",
"this",
"thread_local",
"throw",
"true",
"try",
"typedef",
"typeid",
"typename",
"union",
"unsigned",
"using",
"virtual",
"virtual",
"void",
"volatile",
"wchar_t",
"while",
"xor",
"xor_eq",
// Metal Spec
"access",
"array",
"array_ref",
"as_type",
"atomic",
"atomic_bool",
"atomic_int",
"atomic_uint",
"bool2",
"bool3",
"bool4",
"buffer",
"char2",
"char3",
"char4",
"const_reference",
"constant",
"depth2d",
"depth2d_array",
"depth2d_ms",
"depth2d_ms_array",
"depthcube",
"depthcube_array",
"device",
"discard_fragment",
"float2",
"float2x2",
"float2x3",
"float2x4",
"float3",
"float3x2",
"float3x3",
"float3x4",
"float4",
"float4x2",
"float4x3",
"float4x4",
"fragment",
"half",
"half2",
"half2x2",
"half2x3",
"half2x4",
"half3",
"half3x2",
"half3x3",
"half3x4",
"half4",
"half4x2",
"half4x3",
"half4x4",
"imageblock",
"int16_t",
"int2",
"int3",
"int32_t",
"int4",
"int64_t",
"int8_t",
"kernel",
"long2",
"long3",
"long4",
"main", // No functions called main
"metal", // The namespace
"packed_bool2",
"packed_bool3",
"packed_bool4",
"packed_char2",
"packed_char3",
"packed_char4",
"packed_float2",
"packed_float3",
"packed_float4",
"packed_half2",
"packed_half3",
"packed_half4",
"packed_int2",
"packed_int3",
"packed_int4",
"packed_short2",
"packed_short3",
"packed_short4",
"packed_uchar2",
"packed_uchar3",
"packed_uchar4",
"packed_uint2",
"packed_uint3",
"packed_uint4",
"packed_ushort2",
"packed_ushort3",
"packed_ushort4",
"patch_control_point",
"ptrdiff_t",
"r16snorm",
"r16unorm",
"r8unorm",
"reference",
"rg11b10f",
"rg16snorm",
"rg16unorm",
"rg8snorm",
"rg8unorm",
"rgb10a2",
"rgb9e5",
"rgba16snorm",
"rgba16unorm",
"rgba8snorm",
"rgba8unorm",
"sampler",
"short2",
"short3",
"short4",
"size_t",
"srgba8unorm",
"texture",
"texture1d",
"texture1d_array",
"texture2d",
"texture2d_array",
"texture2d_ms",
"texture2d_ms_array",
"texture3d",
"texture_buffer",
"texturecube",
"texturecube_array",
"thread",
"threadgroup",
"threadgroup_imageblock",
"uchar",
"uchar2",
"uchar3",
"uchar4",
"uint",
"uint16_t",
"uint2",
"uint3",
"uint32_t",
"uint4",
"uint64_t",
"uint8_t",
"ulong2",
"ulong3",
"ulong4",
"uniform",
"ushort",
"ushort2",
"ushort3",
"ushort4",
"vec",
"vertex"));
} // namespace
} // namespace msl
} // namespace writer
} // namespace tint