• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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