• 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_CASE_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_CASE_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_CASE_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_CASE_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