1 // 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 "gmock/gmock.h"
16 #include "src/reader/spirv/function.h"
17 #include "src/reader/spirv/parser_impl_test_helper.h"
18 #include "src/reader/spirv/spirv_tools_helpers_test.h"
19
20 namespace tint {
21 namespace reader {
22 namespace spirv {
23 namespace {
24
25 using ::testing::HasSubstr;
26
Preamble()27 std::string Preamble() {
28 return R"(
29 OpCapability Shader
30 OpMemoryModel Logical Simple
31 OpEntryPoint Fragment %100 "x_100"
32 OpExecutionMode %100 OriginUpperLeft
33 )";
34 }
35
36 /// @returns a SPIR-V assembly segment which assigns debug names
37 /// to particular IDs.
Names(std::vector<std::string> ids)38 std::string Names(std::vector<std::string> ids) {
39 std::ostringstream outs;
40 for (auto& id : ids) {
41 outs << " OpName %" << id << " \"" << id << "\"\n";
42 }
43 return outs.str();
44 }
45
CommonTypes()46 std::string CommonTypes() {
47 return R"(
48 %void = OpTypeVoid
49 %voidfn = OpTypeFunction %void
50 %float = OpTypeFloat 32
51 %uint = OpTypeInt 32 0
52 %int = OpTypeInt 32 1
53 %float_0 = OpConstant %float 0.0
54 )";
55 }
56
MainBody()57 std::string MainBody() {
58 return R"(
59 %100 = OpFunction %void None %voidfn
60 %entry_100 = OpLabel
61 OpReturn
62 OpFunctionEnd
63 )";
64 }
65
TEST_F(SpvParserTest,Emit_VoidFunctionWithoutParams)66 TEST_F(SpvParserTest, Emit_VoidFunctionWithoutParams) {
67 auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
68 %100 = OpFunction %void None %voidfn
69 %entry = OpLabel
70 OpReturn
71 OpFunctionEnd
72 )"));
73 ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
74 auto fe = p->function_emitter(100);
75 EXPECT_TRUE(fe.Emit());
76 auto got = test::ToString(p->program());
77 std::string expect = R"(fn x_100() {
78 return;
79 }
80 )";
81 EXPECT_EQ(got, expect);
82 }
83
TEST_F(SpvParserTest,Emit_NonVoidResultType)84 TEST_F(SpvParserTest, Emit_NonVoidResultType) {
85 auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
86 %fn_ret_float = OpTypeFunction %float
87 %200 = OpFunction %float None %fn_ret_float
88 %entry = OpLabel
89 OpReturnValue %float_0
90 OpFunctionEnd
91 )" + MainBody()));
92 ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
93 auto fe = p->function_emitter(200);
94 EXPECT_TRUE(fe.Emit());
95
96 auto got = test::ToString(p->program());
97 std::string expect = R"(fn x_200() -> f32 {
98 return 0.0;
99 }
100 )";
101 EXPECT_THAT(got, HasSubstr(expect));
102 }
103
TEST_F(SpvParserTest,Emit_MixedParamTypes)104 TEST_F(SpvParserTest, Emit_MixedParamTypes) {
105 auto p = parser(
106 test::Assemble(Preamble() + Names({"a", "b", "c"}) + CommonTypes() + R"(
107 %fn_mixed_params = OpTypeFunction %void %uint %float %int
108
109 %200 = OpFunction %void None %fn_mixed_params
110 %a = OpFunctionParameter %uint
111 %b = OpFunctionParameter %float
112 %c = OpFunctionParameter %int
113 %mixed_entry = OpLabel
114 OpReturn
115 OpFunctionEnd
116 )" + MainBody()));
117 ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
118 auto fe = p->function_emitter(200);
119 EXPECT_TRUE(fe.Emit());
120
121 auto got = test::ToString(p->program());
122 std::string expect = R"(fn x_200(a : u32, b : f32, c : i32) {
123 return;
124 }
125 )";
126 EXPECT_THAT(got, HasSubstr(expect));
127 }
128
TEST_F(SpvParserTest,Emit_GenerateParamNames)129 TEST_F(SpvParserTest, Emit_GenerateParamNames) {
130 auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
131 %fn_mixed_params = OpTypeFunction %void %uint %float %int
132
133 %200 = OpFunction %void None %fn_mixed_params
134 %14 = OpFunctionParameter %uint
135 %15 = OpFunctionParameter %float
136 %16 = OpFunctionParameter %int
137 %mixed_entry = OpLabel
138 OpReturn
139 OpFunctionEnd
140 )" + MainBody()));
141 ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
142 auto fe = p->function_emitter(200);
143 EXPECT_TRUE(fe.Emit());
144
145 auto got = test::ToString(p->program());
146 std::string expect = R"(fn x_200(x_14 : u32, x_15 : f32, x_16 : i32) {
147 return;
148 }
149 )";
150 EXPECT_THAT(got, HasSubstr(expect));
151 }
152
153 } // namespace
154 } // namespace spirv
155 } // namespace reader
156 } // namespace tint
157