blob: 25ff811362395da671bd5afa48d2b378cbacdb0d [file] [log] [blame]
dan sinclair99ad0e82020-07-25 14:39:23 +00001// Copyright 2020 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "gtest/gtest.h"
16#include "src/ast/call_expression.h"
17#include "src/ast/identifier_expression.h"
18#include "src/ast/module.h"
19#include "src/ast/type/f32_type.h"
20#include "src/ast/type/vector_type.h"
dan sinclair99ad0e82020-07-25 14:39:23 +000021#include "src/type_determiner.h"
22#include "src/writer/msl/generator_impl.h"
dan sinclair196e0972020-11-13 18:13:24 +000023#include "src/writer/msl/test_helper.h"
dan sinclair99ad0e82020-07-25 14:39:23 +000024
25namespace tint {
26namespace writer {
27namespace msl {
28namespace {
29
dan sinclair196e0972020-11-13 18:13:24 +000030using MslGeneratorImplTest = TestHelper;
dan sinclair99ad0e82020-07-25 14:39:23 +000031
32struct IntrinsicData {
dan sinclairb4fee2f2020-09-22 19:42:13 +000033 ast::Intrinsic intrinsic;
dan sinclair99ad0e82020-07-25 14:39:23 +000034 const char* msl_name;
35};
36inline std::ostream& operator<<(std::ostream& out, IntrinsicData data) {
dan sinclairb4fee2f2020-09-22 19:42:13 +000037 out << data.msl_name;
dan sinclair99ad0e82020-07-25 14:39:23 +000038 return out;
39}
dan sinclair196e0972020-11-13 18:13:24 +000040using MslIntrinsicTest = TestParamHelper<IntrinsicData>;
dan sinclair99ad0e82020-07-25 14:39:23 +000041TEST_P(MslIntrinsicTest, Emit) {
42 auto param = GetParam();
dan sinclair196e0972020-11-13 18:13:24 +000043 EXPECT_EQ(gen.generate_intrinsic_name(param.intrinsic), param.msl_name);
dan sinclair99ad0e82020-07-25 14:39:23 +000044}
dan sinclairb4fee2f2020-09-22 19:42:13 +000045INSTANTIATE_TEST_SUITE_P(
46 MslGeneratorImplTest,
47 MslIntrinsicTest,
48 testing::Values(IntrinsicData{ast::Intrinsic::kAny, "any"},
49 IntrinsicData{ast::Intrinsic::kAll, "all"},
dan sinclair94b7c662020-10-05 19:46:16 +000050 IntrinsicData{ast::Intrinsic::kCountOneBits, "popcount"},
dan sinclairb4fee2f2020-09-22 19:42:13 +000051 IntrinsicData{ast::Intrinsic::kDot, "dot"},
52 IntrinsicData{ast::Intrinsic::kDpdx, "dfdx"},
53 IntrinsicData{ast::Intrinsic::kDpdxCoarse, "dfdx"},
54 IntrinsicData{ast::Intrinsic::kDpdxFine, "dfdx"},
55 IntrinsicData{ast::Intrinsic::kDpdy, "dfdy"},
56 IntrinsicData{ast::Intrinsic::kDpdyCoarse, "dfdy"},
57 IntrinsicData{ast::Intrinsic::kDpdyFine, "dfdy"},
58 IntrinsicData{ast::Intrinsic::kFwidth, "fwidth"},
59 IntrinsicData{ast::Intrinsic::kFwidthCoarse, "fwidth"},
60 IntrinsicData{ast::Intrinsic::kFwidthFine, "fwidth"},
61 IntrinsicData{ast::Intrinsic::kIsFinite, "isfinite"},
62 IntrinsicData{ast::Intrinsic::kIsInf, "isinf"},
63 IntrinsicData{ast::Intrinsic::kIsNan, "isnan"},
64 IntrinsicData{ast::Intrinsic::kIsNormal, "isnormal"},
dan sinclair94b7c662020-10-05 19:46:16 +000065 IntrinsicData{ast::Intrinsic::kReverseBits, "reverse_bits"},
dan sinclairb4fee2f2020-09-22 19:42:13 +000066 IntrinsicData{ast::Intrinsic::kSelect, "select"}));
dan sinclair99ad0e82020-07-25 14:39:23 +000067
68TEST_F(MslGeneratorImplTest, DISABLED_Intrinsic_OuterProduct) {
dan sinclairb5839932020-12-16 21:38:40 +000069 auto* a = Var("a", ast::StorageClass::kNone, ty.vec2<f32>());
70 auto* b = Var("b", ast::StorageClass::kNone, ty.vec3<f32>());
dan sinclair99ad0e82020-07-25 14:39:23 +000071
dan sinclairf74b90b2021-01-11 16:24:32 +000072 auto* call = Call("outerProduct", "a", "b");
Ben Claytonb053acf2020-11-16 16:31:07 +000073 td.RegisterVariableForTesting(a);
74 td.RegisterVariableForTesting(b);
dan sinclair99ad0e82020-07-25 14:39:23 +000075
dan sinclair5e5e36e2020-12-16 14:41:00 +000076 mod->AddGlobalVariable(a);
77 mod->AddGlobalVariable(b);
dan sinclair99ad0e82020-07-25 14:39:23 +000078
79 ASSERT_TRUE(td.Determine()) << td.error();
dan sinclairb5839932020-12-16 21:38:40 +000080 ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
dan sinclair99ad0e82020-07-25 14:39:23 +000081
dan sinclair196e0972020-11-13 18:13:24 +000082 gen.increment_indent();
dan sinclairb5839932020-12-16 21:38:40 +000083 ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
dan sinclairf74b90b2021-01-11 16:24:32 +000084 EXPECT_EQ(
85 gen.result(),
86 " float3x2(test_a * test_b[0], test_a * test_b[1], test_a * test_b[2])");
dan sinclair99ad0e82020-07-25 14:39:23 +000087}
88
89TEST_F(MslGeneratorImplTest, Intrinsic_Bad_Name) {
dan sinclair196e0972020-11-13 18:13:24 +000090 EXPECT_EQ(gen.generate_intrinsic_name(ast::Intrinsic::kNone), "");
dan sinclair99ad0e82020-07-25 14:39:23 +000091}
92
93TEST_F(MslGeneratorImplTest, Intrinsic_Call) {
dan sinclairb5839932020-12-16 21:38:40 +000094 auto* call = Call("dot", "param1", "param2");
dan sinclairff267ca2020-10-14 18:26:31 +000095
dan sinclairb5839932020-12-16 21:38:40 +000096 auto* v1 = Var("param1", ast::StorageClass::kFunction, ty.vec2<f32>());
97 auto* v2 = Var("param2", ast::StorageClass::kFunction, ty.vec2<f32>());
dan sinclair99ad0e82020-07-25 14:39:23 +000098
dan sinclairb5839932020-12-16 21:38:40 +000099 td.RegisterVariableForTesting(v1);
100 td.RegisterVariableForTesting(v2);
dan sinclair99ad0e82020-07-25 14:39:23 +0000101
dan sinclairb5839932020-12-16 21:38:40 +0000102 ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
dan sinclairb4fee2f2020-09-22 19:42:13 +0000103
dan sinclair196e0972020-11-13 18:13:24 +0000104 gen.increment_indent();
dan sinclairb5839932020-12-16 21:38:40 +0000105 ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
dan sinclairf74b90b2021-01-11 16:24:32 +0000106 EXPECT_EQ(gen.result(), " dot(test_param1, test_param2)");
dan sinclair99ad0e82020-07-25 14:39:23 +0000107}
108
109} // namespace
110} // namespace msl
111} // namespace writer
112} // namespace tint