• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2017 Valve Corporation
2 // Copyright (c) 2017 LunarG Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #include <string>
17 #include <vector>
18 
19 #include "gmock/gmock.h"
20 #include "test/opt/pass_fixture.h"
21 #include "test/opt/pass_utils.h"
22 
23 namespace spvtools {
24 namespace opt {
25 namespace {
26 
27 // Returns the initial part of the assembly text for a valid
28 // SPIR-V module, including instructions prior to decorations.
PreambleAssembly()29 std::string PreambleAssembly() {
30   return
31       R"(OpCapability Shader
32 OpMemoryModel Logical GLSL450
33 OpEntryPoint Fragment %main "main" %hue %saturation %value
34 OpExecutionMode %main OriginUpperLeft
35 OpName %main "main"
36 OpName %void_fn "void_fn"
37 OpName %hue "hue"
38 OpName %saturation "saturation"
39 OpName %value "value"
40 OpName %entry "entry"
41 OpName %Point "Point"
42 OpName %Camera "Camera"
43 )";
44 }
45 
46 // Retuns types
TypesAndFunctionsAssembly()47 std::string TypesAndFunctionsAssembly() {
48   return
49       R"(%void = OpTypeVoid
50 %void_fn = OpTypeFunction %void
51 %float = OpTypeFloat 32
52 %Point = OpTypeStruct %float %float %float
53 %Camera = OpTypeStruct %float %float
54 %_ptr_Input_float = OpTypePointer Input %float
55 %hue = OpVariable %_ptr_Input_float Input
56 %saturation = OpVariable %_ptr_Input_float Input
57 %value = OpVariable %_ptr_Input_float Input
58 %main = OpFunction %void None %void_fn
59 %entry = OpLabel
60 OpReturn
61 OpFunctionEnd
62 )";
63 }
64 
65 struct FlattenDecorationCase {
66   // Names and decorations before the pass.
67   std::string input;
68   // Names and decorations after the pass.
69   std::string expected;
70 };
71 
72 using FlattenDecorationTest =
73     PassTest<::testing::TestWithParam<FlattenDecorationCase>>;
74 
TEST_P(FlattenDecorationTest,TransformsDecorations)75 TEST_P(FlattenDecorationTest, TransformsDecorations) {
76   const auto before =
77       PreambleAssembly() + GetParam().input + TypesAndFunctionsAssembly();
78   const auto after =
79       PreambleAssembly() + GetParam().expected + TypesAndFunctionsAssembly();
80 
81   SinglePassRunAndCheck<FlattenDecorationPass>(before, after, false, true);
82 }
83 
84 INSTANTIATE_TEST_SUITE_P(NoUses, FlattenDecorationTest,
85                          ::testing::ValuesIn(std::vector<FlattenDecorationCase>{
86                              // No OpDecorationGroup
87                              {"", ""},
88 
89                              // OpDecorationGroup without any uses, and
90                              // no OpName.
91                              {"%group = OpDecorationGroup\n", ""},
92 
93                              // OpDecorationGroup without any uses, and
94                              // with OpName targeting it. Proves you must
95                              // remove the names as well.
96                              {"OpName %group \"group\"\n"
97                               "%group = OpDecorationGroup\n",
98                               ""},
99 
100                              // OpDecorationGroup with decorations that
101                              // target it, but no uses in OpGroupDecorate
102                              // or OpGroupMemberDecorate instructions.
103                              {"OpDecorate %group Flat\n"
104                               "OpDecorate %group NoPerspective\n"
105                               "%group = OpDecorationGroup\n",
106                               ""},
107                          }));
108 
109 INSTANTIATE_TEST_SUITE_P(OpGroupDecorate, FlattenDecorationTest,
110                          ::testing::ValuesIn(std::vector<FlattenDecorationCase>{
111                              // One OpGroupDecorate
112                              {"OpName %group \"group\"\n"
113                               "OpDecorate %group Flat\n"
114                               "OpDecorate %group NoPerspective\n"
115                               "%group = OpDecorationGroup\n"
116                               "OpGroupDecorate %group %hue %saturation\n",
117                               "OpDecorate %hue Flat\n"
118                               "OpDecorate %saturation Flat\n"
119                               "OpDecorate %hue NoPerspective\n"
120                               "OpDecorate %saturation NoPerspective\n"},
121                              // Multiple OpGroupDecorate
122                              {"OpName %group \"group\"\n"
123                               "OpDecorate %group Flat\n"
124                               "OpDecorate %group NoPerspective\n"
125                               "%group = OpDecorationGroup\n"
126                               "OpGroupDecorate %group %hue %value\n"
127                               "OpGroupDecorate %group %saturation\n",
128                               "OpDecorate %hue Flat\n"
129                               "OpDecorate %value Flat\n"
130                               "OpDecorate %saturation Flat\n"
131                               "OpDecorate %hue NoPerspective\n"
132                               "OpDecorate %value NoPerspective\n"
133                               "OpDecorate %saturation NoPerspective\n"},
134                              // Two group decorations, interleaved
135                              {"OpName %group0 \"group0\"\n"
136                               "OpName %group1 \"group1\"\n"
137                               "OpDecorate %group0 Flat\n"
138                               "OpDecorate %group1 NoPerspective\n"
139                               "%group0 = OpDecorationGroup\n"
140                               "%group1 = OpDecorationGroup\n"
141                               "OpGroupDecorate %group0 %hue %value\n"
142                               "OpGroupDecorate %group1 %saturation\n",
143                               "OpDecorate %hue Flat\n"
144                               "OpDecorate %value Flat\n"
145                               "OpDecorate %saturation NoPerspective\n"},
146                              // Decoration with operands
147                              {"OpName %group \"group\"\n"
148                               "OpDecorate %group Location 42\n"
149                               "%group = OpDecorationGroup\n"
150                               "OpGroupDecorate %group %hue %saturation\n",
151                               "OpDecorate %hue Location 42\n"
152                               "OpDecorate %saturation Location 42\n"},
153                          }));
154 
155 INSTANTIATE_TEST_SUITE_P(OpGroupMemberDecorate, FlattenDecorationTest,
156                          ::testing::ValuesIn(std::vector<FlattenDecorationCase>{
157                              // One OpGroupMemberDecorate
158                              {"OpName %group \"group\"\n"
159                               "OpDecorate %group Flat\n"
160                               "OpDecorate %group Offset 16\n"
161                               "%group = OpDecorationGroup\n"
162                               "OpGroupMemberDecorate %group %Point 1\n",
163                               "OpMemberDecorate %Point 1 Flat\n"
164                               "OpMemberDecorate %Point 1 Offset 16\n"},
165                              // Multiple OpGroupMemberDecorate using the same
166                              // decoration group.
167                              {"OpName %group \"group\"\n"
168                               "OpDecorate %group Flat\n"
169                               "OpDecorate %group NoPerspective\n"
170                               "OpDecorate %group Offset 8\n"
171                               "%group = OpDecorationGroup\n"
172                               "OpGroupMemberDecorate %group %Point 2\n"
173                               "OpGroupMemberDecorate %group %Camera 1\n",
174                               "OpMemberDecorate %Point 2 Flat\n"
175                               "OpMemberDecorate %Camera 1 Flat\n"
176                               "OpMemberDecorate %Point 2 NoPerspective\n"
177                               "OpMemberDecorate %Camera 1 NoPerspective\n"
178                               "OpMemberDecorate %Point 2 Offset 8\n"
179                               "OpMemberDecorate %Camera 1 Offset 8\n"},
180                              // Two groups of member decorations, interleaved.
181                              // Decoration is with and without operands.
182                              {"OpName %group0 \"group0\"\n"
183                               "OpName %group1 \"group1\"\n"
184                               "OpDecorate %group0 Flat\n"
185                               "OpDecorate %group0 Offset 8\n"
186                               "OpDecorate %group1 NoPerspective\n"
187                               "OpDecorate %group1 Offset 16\n"
188                               "%group0 = OpDecorationGroup\n"
189                               "%group1 = OpDecorationGroup\n"
190                               "OpGroupMemberDecorate %group0 %Point 0\n"
191                               "OpGroupMemberDecorate %group1 %Point 2\n",
192                               "OpMemberDecorate %Point 0 Flat\n"
193                               "OpMemberDecorate %Point 0 Offset 8\n"
194                               "OpMemberDecorate %Point 2 NoPerspective\n"
195                               "OpMemberDecorate %Point 2 Offset 16\n"},
196                          }));
197 
198 INSTANTIATE_TEST_SUITE_P(UnrelatedDecorations, FlattenDecorationTest,
199                          ::testing::ValuesIn(std::vector<FlattenDecorationCase>{
200                              // A non-group non-member decoration is untouched.
201                              {"OpDecorate %hue Centroid\n"
202                               "OpDecorate %saturation Flat\n",
203                               "OpDecorate %hue Centroid\n"
204                               "OpDecorate %saturation Flat\n"},
205                              // A non-group member decoration is untouched.
206                              {"OpMemberDecorate %Point 0 Offset 0\n"
207                               "OpMemberDecorate %Point 1 Offset 4\n"
208                               "OpMemberDecorate %Point 1 Flat\n",
209                               "OpMemberDecorate %Point 0 Offset 0\n"
210                               "OpMemberDecorate %Point 1 Offset 4\n"
211                               "OpMemberDecorate %Point 1 Flat\n"},
212                              // A non-group non-member decoration survives any
213                              // replacement of group decorations.
214                              {"OpName %group \"group\"\n"
215                               "OpDecorate %group Flat\n"
216                               "OpDecorate %hue Centroid\n"
217                               "OpDecorate %group NoPerspective\n"
218                               "%group = OpDecorationGroup\n"
219                               "OpGroupDecorate %group %hue %saturation\n",
220                               "OpDecorate %hue Flat\n"
221                               "OpDecorate %saturation Flat\n"
222                               "OpDecorate %hue Centroid\n"
223                               "OpDecorate %hue NoPerspective\n"
224                               "OpDecorate %saturation NoPerspective\n"},
225                              // A non-group member decoration survives any
226                              // replacement of group decorations.
227                              {"OpDecorate %group Offset 0\n"
228                               "OpDecorate %group Flat\n"
229                               "OpMemberDecorate %Point 1 Offset 4\n"
230                               "%group = OpDecorationGroup\n"
231                               "OpGroupMemberDecorate %group %Point 0\n",
232                               "OpMemberDecorate %Point 0 Offset 0\n"
233                               "OpMemberDecorate %Point 0 Flat\n"
234                               "OpMemberDecorate %Point 1 Offset 4\n"},
235                          }));
236 
237 }  // namespace
238 }  // namespace opt
239 }  // namespace spvtools
240