• 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   %glsl = OpExtInstImport "GLSL.std.450"
31   OpMemoryModel Logical GLSL450
32   OpEntryPoint GLCompute %100 "main"
33   OpExecutionMode %100 LocalSize 1 1 1
34 
35   OpName %u1 "u1"
36   OpName %u2 "u2"
37   OpName %u3 "u3"
38   OpName %i1 "i1"
39   OpName %i2 "i2"
40   OpName %i3 "i3"
41   OpName %f1 "f1"
42   OpName %f2 "f2"
43   OpName %f3 "f3"
44   OpName %v2u1 "v2u1"
45   OpName %v2u2 "v2u2"
46   OpName %v2u3 "v2u3"
47   OpName %v2i1 "v2i1"
48   OpName %v2i2 "v2i2"
49   OpName %v2i3 "v2i3"
50   OpName %v2f1 "v2f1"
51   OpName %v2f2 "v2f2"
52   OpName %v2f3 "v2f3"
53   OpName %v3f1 "v3f1"
54   OpName %v3f2 "v3f2"
55   OpName %v4f1 "v4f1"
56   OpName %v4f2 "v4f2"
57 
58   %void = OpTypeVoid
59   %voidfn = OpTypeFunction %void
60 
61   %uint = OpTypeInt 32 0
62   %int = OpTypeInt 32 1
63   %float = OpTypeFloat 32
64 
65   %uint_10 = OpConstant %uint 10
66   %uint_15 = OpConstant %uint 15
67   %uint_20 = OpConstant %uint 20
68   %int_30 = OpConstant %int 30
69   %int_35 = OpConstant %int 35
70   %int_40 = OpConstant %int 40
71   %float_50 = OpConstant %float 50
72   %float_60 = OpConstant %float 60
73   %float_70 = OpConstant %float 70
74 
75   %v2uint = OpTypeVector %uint 2
76   %v2int = OpTypeVector %int 2
77   %v2float = OpTypeVector %float 2
78   %v3float = OpTypeVector %float 3
79   %v4float = OpTypeVector %float 4
80 
81   %v2uint_10_20 = OpConstantComposite %v2uint %uint_10 %uint_20
82   %v2uint_20_10 = OpConstantComposite %v2uint %uint_20 %uint_10
83   %v2uint_15_15 = OpConstantComposite %v2uint %uint_15 %uint_15
84   %v2int_30_40 = OpConstantComposite %v2int %int_30 %int_40
85   %v2int_40_30 = OpConstantComposite %v2int %int_40 %int_30
86   %v2int_35_35 = OpConstantComposite %v2int %int_35 %int_35
87   %v2float_50_60 = OpConstantComposite %v2float %float_50 %float_60
88   %v2float_60_50 = OpConstantComposite %v2float %float_60 %float_50
89   %v2float_70_70 = OpConstantComposite %v2float %float_70 %float_70
90 
91   %v3float_50_60_70 = OpConstantComposite %v3float %float_50 %float_60 %float_70
92   %v3float_60_70_50 = OpConstantComposite %v3float %float_60 %float_70 %float_50
93 
94   %v4float_50_50_50_50 = OpConstantComposite %v4float %float_50 %float_50 %float_50 %float_50
95 
96   %100 = OpFunction %void None %voidfn
97   %entry = OpLabel
98 
99   %u1 = OpCopyObject %uint %uint_10
100   %u2 = OpCopyObject %uint %uint_15
101   %u3 = OpCopyObject %uint %uint_20
102 
103   %i1 = OpCopyObject %int %int_30
104   %i2 = OpCopyObject %int %int_35
105   %i3 = OpCopyObject %int %int_40
106 
107   %f1 = OpCopyObject %float %float_50
108   %f2 = OpCopyObject %float %float_60
109   %f3 = OpCopyObject %float %float_70
110 
111   %v2u1 = OpCopyObject %v2uint %v2uint_10_20
112   %v2u2 = OpCopyObject %v2uint %v2uint_20_10
113   %v2u3 = OpCopyObject %v2uint %v2uint_15_15
114 
115   %v2i1 = OpCopyObject %v2int %v2int_30_40
116   %v2i2 = OpCopyObject %v2int %v2int_40_30
117   %v2i3 = OpCopyObject %v2int %v2int_35_35
118 
119   %v2f1 = OpCopyObject %v2float %v2float_50_60
120   %v2f2 = OpCopyObject %v2float %v2float_60_50
121   %v2f3 = OpCopyObject %v2float %v2float_70_70
122 
123   %v3f1 = OpCopyObject %v3float %v3float_50_60_70
124   %v3f2 = OpCopyObject %v3float %v3float_60_70_50
125 
126   %v4f1 = OpCopyObject %v4float %v4float_50_50_50_50
127   %v4f2 = OpCopyObject %v4float %v4f1
128 )";
129 }
130 
131 struct GlslStd450Case {
132   std::string opcode;
133   std::string wgsl_func;
134 };
operator <<(std::ostream & out,GlslStd450Case c)135 inline std::ostream& operator<<(std::ostream& out, GlslStd450Case c) {
136   out << "GlslStd450Case(" << c.opcode << " " << c.wgsl_func << ")";
137   return out;
138 }
139 
140 // Nomenclature:
141 // Float = scalar float
142 // Floating = scalar float or vector-of-float
143 // Float3 = 3-element vector of float
144 // Int = scalar signed int
145 // Inting = scalar int or vector-of-int
146 // Uint = scalar unsigned int
147 // Uinting = scalar unsigned or vector-of-unsigned
148 
149 using SpvParserTest_GlslStd450_Float_Floating =
150     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
151 using SpvParserTest_GlslStd450_Float_FloatingFloating =
152     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
153 using SpvParserTest_GlslStd450_Floating_Floating =
154     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
155 using SpvParserTest_GlslStd450_Floating_FloatingFloating =
156     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
157 using SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating =
158     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
159 using SpvParserTest_GlslStd450_Floating_FloatingInting =
160     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
161 using SpvParserTest_GlslStd450_Float3_Float3Float3 =
162     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
163 
164 using SpvParserTest_GlslStd450_Inting_Inting =
165     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
166 using SpvParserTest_GlslStd450_Inting_IntingInting =
167     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
168 using SpvParserTest_GlslStd450_Inting_IntingIntingInting =
169     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
170 using SpvParserTest_GlslStd450_Uinting_UintingUinting =
171     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
172 using SpvParserTest_GlslStd450_Uinting_UintingUintingUinting =
173     SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
174 
TEST_P(SpvParserTest_GlslStd450_Float_Floating,Scalar)175 TEST_P(SpvParserTest_GlslStd450_Float_Floating, Scalar) {
176   const auto assembly = Preamble() + R"(
177      %1 = OpExtInst %float %glsl )" +
178                         GetParam().opcode + R"( %f1
179      OpReturn
180      OpFunctionEnd
181   )";
182   auto p = parser(test::Assemble(assembly));
183   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
184   auto fe = p->function_emitter(100);
185   EXPECT_TRUE(fe.EmitBody()) << p->error();
186   auto ast_body = fe.ast_body();
187   const auto body = test::ToString(p->program(), ast_body);
188   EXPECT_THAT(body,
189               HasSubstr("let x_1 : f32 = " + GetParam().wgsl_func + "(f1);"))
190       << body;
191 }
192 
TEST_P(SpvParserTest_GlslStd450_Float_Floating,Vector)193 TEST_P(SpvParserTest_GlslStd450_Float_Floating, Vector) {
194   const auto assembly = Preamble() + R"(
195      %1 = OpExtInst %float %glsl )" +
196                         GetParam().opcode + R"( %v2f1
197      OpReturn
198      OpFunctionEnd
199   )";
200   auto p = parser(test::Assemble(assembly));
201   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
202   auto fe = p->function_emitter(100);
203   EXPECT_TRUE(fe.EmitBody()) << p->error();
204   auto ast_body = fe.ast_body();
205   const auto body = test::ToString(p->program(), ast_body);
206   EXPECT_THAT(body,
207               HasSubstr("let x_1 : f32 = " + GetParam().wgsl_func + "(v2f1);"))
208       << body;
209 }
210 
TEST_P(SpvParserTest_GlslStd450_Float_FloatingFloating,Scalar)211 TEST_P(SpvParserTest_GlslStd450_Float_FloatingFloating, Scalar) {
212   const auto assembly = Preamble() + R"(
213      %1 = OpExtInst %float %glsl )" +
214                         GetParam().opcode + R"( %f1 %f2
215      OpReturn
216      OpFunctionEnd
217   )";
218   auto p = parser(test::Assemble(assembly));
219   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
220   auto fe = p->function_emitter(100);
221   EXPECT_TRUE(fe.EmitBody()) << p->error();
222   auto ast_body = fe.ast_body();
223   const auto body = test::ToString(p->program(), ast_body);
224   EXPECT_THAT(
225       body, HasSubstr("let x_1 : f32 = " + GetParam().wgsl_func + "(f1, f2);"))
226       << body;
227 }
228 
TEST_P(SpvParserTest_GlslStd450_Float_FloatingFloating,Vector)229 TEST_P(SpvParserTest_GlslStd450_Float_FloatingFloating, Vector) {
230   const auto assembly = Preamble() + R"(
231      %1 = OpExtInst %float %glsl )" +
232                         GetParam().opcode + R"( %v2f1 %v2f2
233      OpReturn
234      OpFunctionEnd
235   )";
236   auto p = parser(test::Assemble(assembly));
237   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
238   auto fe = p->function_emitter(100);
239   EXPECT_TRUE(fe.EmitBody()) << p->error();
240   auto ast_body = fe.ast_body();
241   const auto body = test::ToString(p->program(), ast_body);
242   EXPECT_THAT(body, HasSubstr("let x_1 : f32 = " + GetParam().wgsl_func +
243                               "(v2f1, v2f2);"))
244       << body;
245 }
246 
TEST_P(SpvParserTest_GlslStd450_Floating_Floating,Scalar)247 TEST_P(SpvParserTest_GlslStd450_Floating_Floating, Scalar) {
248   const auto assembly = Preamble() + R"(
249      %1 = OpExtInst %float %glsl )" +
250                         GetParam().opcode + R"( %f1
251      OpReturn
252      OpFunctionEnd
253   )";
254   auto p = parser(test::Assemble(assembly));
255   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
256   auto fe = p->function_emitter(100);
257   EXPECT_TRUE(fe.EmitBody()) << p->error();
258   auto ast_body = fe.ast_body();
259   const auto body = test::ToString(p->program(), ast_body);
260   EXPECT_THAT(body,
261               HasSubstr("let x_1 : f32 = " + GetParam().wgsl_func + "(f1);"))
262       << body;
263 }
264 
TEST_P(SpvParserTest_GlslStd450_Floating_Floating,Vector)265 TEST_P(SpvParserTest_GlslStd450_Floating_Floating, Vector) {
266   const auto assembly = Preamble() + R"(
267      %1 = OpExtInst %v2float %glsl )" +
268                         GetParam().opcode + R"( %v2f1
269      OpReturn
270      OpFunctionEnd
271   )";
272   auto p = parser(test::Assemble(assembly));
273   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
274   auto fe = p->function_emitter(100);
275   EXPECT_TRUE(fe.EmitBody()) << p->error();
276   auto ast_body = fe.ast_body();
277   const auto body = test::ToString(p->program(), ast_body);
278   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<f32> = " + GetParam().wgsl_func +
279                               "(v2f1);"))
280       << body;
281 }
282 
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloating,Scalar)283 TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloating, Scalar) {
284   const auto assembly = Preamble() + R"(
285      %1 = OpExtInst %float %glsl )" +
286                         GetParam().opcode + R"( %f1 %f2
287      OpReturn
288      OpFunctionEnd
289   )";
290   auto p = parser(test::Assemble(assembly));
291   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
292   auto fe = p->function_emitter(100);
293   EXPECT_TRUE(fe.EmitBody()) << p->error();
294   auto ast_body = fe.ast_body();
295   const auto body = test::ToString(p->program(), ast_body);
296   EXPECT_THAT(
297       body, HasSubstr("let x_1 : f32 = " + GetParam().wgsl_func + "(f1, f2);"))
298       << body;
299 }
300 
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloating,Vector)301 TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloating, Vector) {
302   const auto assembly = Preamble() + R"(
303      %1 = OpExtInst %v2float %glsl )" +
304                         GetParam().opcode + R"( %v2f1 %v2f2
305      OpReturn
306      OpFunctionEnd
307   )";
308   auto p = parser(test::Assemble(assembly));
309   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
310   auto fe = p->function_emitter(100);
311   EXPECT_TRUE(fe.EmitBody()) << p->error();
312   auto ast_body = fe.ast_body();
313   const auto body = test::ToString(p->program(), ast_body);
314   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<f32> = " + GetParam().wgsl_func +
315                               "(v2f1, v2f2);"))
316       << body;
317 }
318 
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating,Scalar)319 TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating, Scalar) {
320   const auto assembly = Preamble() + R"(
321      %1 = OpExtInst %float %glsl )" +
322                         GetParam().opcode + R"( %f1 %f2 %f3
323      OpReturn
324      OpFunctionEnd
325   )";
326   auto p = parser(test::Assemble(assembly));
327   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
328   auto fe = p->function_emitter(100);
329   EXPECT_TRUE(fe.EmitBody()) << p->error();
330   auto ast_body = fe.ast_body();
331   const auto body = test::ToString(p->program(), ast_body);
332   EXPECT_THAT(body, HasSubstr("let x_1 : f32 = " + GetParam().wgsl_func +
333                               "(f1, f2, f3);"))
334       << body;
335 }
336 
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating,Vector)337 TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating, Vector) {
338   const auto assembly = Preamble() + R"(
339      %1 = OpExtInst %v2float %glsl )" +
340                         GetParam().opcode +
341                         R"( %v2f1 %v2f2 %v2f3
342      OpReturn
343      OpFunctionEnd
344   )";
345   auto p = parser(test::Assemble(assembly));
346   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
347   auto fe = p->function_emitter(100);
348   EXPECT_TRUE(fe.EmitBody()) << p->error();
349   auto ast_body = fe.ast_body();
350   const auto body = test::ToString(p->program(), ast_body);
351   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<f32> = " + GetParam().wgsl_func +
352                               "(v2f1, v2f2, v2f3);"))
353       << body;
354 }
355 
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting,Scalar)356 TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting, Scalar) {
357   const auto assembly = Preamble() + R"(
358      %1 = OpExtInst %float %glsl )" +
359                         GetParam().opcode + R"( %f1 %i1
360      OpReturn
361      OpFunctionEnd
362   )";
363   auto p = parser(test::Assemble(assembly));
364   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
365   auto fe = p->function_emitter(100);
366   EXPECT_TRUE(fe.EmitBody()) << p->error();
367   auto ast_body = fe.ast_body();
368   const auto body = test::ToString(p->program(), ast_body);
369   EXPECT_THAT(
370       body, HasSubstr("let x_1 : f32 = " + GetParam().wgsl_func + "(f1, i1);"))
371       << body;
372 }
373 
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting,Vector)374 TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting, Vector) {
375   const auto assembly = Preamble() + R"(
376      %1 = OpExtInst %v2float %glsl )" +
377                         GetParam().opcode +
378                         R"( %v2f1 %v2i1
379      OpReturn
380      OpFunctionEnd
381   )";
382   auto p = parser(test::Assemble(assembly));
383   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
384   auto fe = p->function_emitter(100);
385   EXPECT_TRUE(fe.EmitBody()) << p->error();
386   auto ast_body = fe.ast_body();
387   const auto body = test::ToString(p->program(), ast_body);
388   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<f32> = " + GetParam().wgsl_func +
389                               "(v2f1, v2i1);"))
390       << body;
391 }
392 
TEST_P(SpvParserTest_GlslStd450_Float3_Float3Float3,Samples)393 TEST_P(SpvParserTest_GlslStd450_Float3_Float3Float3, Samples) {
394   const auto assembly = Preamble() + R"(
395      %1 = OpExtInst %v3float %glsl )" +
396                         GetParam().opcode +
397                         R"( %v3f1 %v3f2
398      OpReturn
399      OpFunctionEnd
400   )";
401   auto p = parser(test::Assemble(assembly));
402   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
403   auto fe = p->function_emitter(100);
404   EXPECT_TRUE(fe.EmitBody()) << p->error();
405   auto ast_body = fe.ast_body();
406   const auto body = test::ToString(p->program(), ast_body);
407   EXPECT_THAT(body, HasSubstr("let x_1 : vec3<f32> = " + GetParam().wgsl_func +
408                               "(v3f1, v3f2);"))
409       << body;
410 }
411 
412 INSTANTIATE_TEST_SUITE_P(Samples,
413                          SpvParserTest_GlslStd450_Float_Floating,
414                          ::testing::Values(GlslStd450Case{"Length", "length"}));
415 
416 INSTANTIATE_TEST_SUITE_P(Samples,
417                          SpvParserTest_GlslStd450_Float_FloatingFloating,
418                          ::testing::Values(GlslStd450Case{"Distance",
419                                                           "distance"}));
420 
421 INSTANTIATE_TEST_SUITE_P(Samples,
422                          SpvParserTest_GlslStd450_Floating_Floating,
423                          ::testing::ValuesIn(std::vector<GlslStd450Case>{
424                              {"Acos", "acos"},
425                              {"Asin", "asin"},
426                              {"Atan", "atan"},
427                              {"Ceil", "ceil"},
428                              {"Cos", "cos"},
429                              {"Cosh", "cosh"},
430                              {"Exp", "exp"},
431                              {"Exp2", "exp2"},
432                              {"FAbs", "abs"},
433                              {"FSign", "sign"},
434                              {"Floor", "floor"},
435                              {"Fract", "fract"},
436                              {"InverseSqrt", "inverseSqrt"},
437                              {"Log", "log"},
438                              {"Log2", "log2"},
439                              {"Round", "round"},
440                              {"RoundEven", "round"},
441                              {"Sin", "sin"},
442                              {"Sinh", "sinh"},
443                              {"Sqrt", "sqrt"},
444                              {"Tan", "tan"},
445                              {"Tanh", "tanh"},
446                              {"Trunc", "trunc"},
447                          }));
448 
449 INSTANTIATE_TEST_SUITE_P(Samples,
450                          SpvParserTest_GlslStd450_Floating_FloatingFloating,
451                          ::testing::ValuesIn(std::vector<GlslStd450Case>{
452                              {"Atan2", "atan2"},
453                              {"NMax", "max"},
454                              {"NMin", "min"},
455                              {"FMax", "max"},  // WGSL max promises more for NaN
456                              {"FMin", "min"},  // WGSL min promises more for NaN
457                              {"Pow", "pow"},
458                              {"Step", "step"},
459                          }));
460 
461 INSTANTIATE_TEST_SUITE_P(Samples,
462                          SpvParserTest_GlslStd450_Floating_FloatingInting,
463                          ::testing::Values(GlslStd450Case{"Ldexp", "ldexp"}));
464 // For ldexp with unsigned second argument, see below.
465 
466 INSTANTIATE_TEST_SUITE_P(Samples,
467                          SpvParserTest_GlslStd450_Float3_Float3Float3,
468                          ::testing::Values(GlslStd450Case{"Cross", "cross"}));
469 
470 INSTANTIATE_TEST_SUITE_P(
471     Samples,
472     SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating,
473     ::testing::ValuesIn(std::vector<GlslStd450Case>{
474         {"NClamp", "clamp"},
475         {"FClamp", "clamp"},  // WGSL FClamp promises more for NaN
476         {"Fma", "fma"},
477         {"FMix", "mix"},
478         {"SmoothStep", "smoothStep"}}));
479 
TEST_P(SpvParserTest_GlslStd450_Inting_Inting,Scalar)480 TEST_P(SpvParserTest_GlslStd450_Inting_Inting, Scalar) {
481   const auto assembly = Preamble() + R"(
482      %1 = OpExtInst %int %glsl )" +
483                         GetParam().opcode +
484                         R"( %i1
485      OpReturn
486      OpFunctionEnd
487   )";
488   auto p = parser(test::Assemble(assembly));
489   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
490   auto fe = p->function_emitter(100);
491   EXPECT_TRUE(fe.EmitBody()) << p->error();
492   auto ast_body = fe.ast_body();
493   const auto body = test::ToString(p->program(), ast_body);
494   EXPECT_THAT(body,
495               HasSubstr("let x_1 : i32 = " + GetParam().wgsl_func + "(i1);"))
496       << body;
497 }
498 
TEST_P(SpvParserTest_GlslStd450_Inting_Inting,Vector)499 TEST_P(SpvParserTest_GlslStd450_Inting_Inting, Vector) {
500   const auto assembly = Preamble() + R"(
501      %1 = OpExtInst %v2int %glsl )" +
502                         GetParam().opcode +
503                         R"( %v2i1
504      OpReturn
505      OpFunctionEnd
506   )";
507   auto p = parser(test::Assemble(assembly));
508   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
509   auto fe = p->function_emitter(100);
510   EXPECT_TRUE(fe.EmitBody()) << p->error();
511   auto ast_body = fe.ast_body();
512   const auto body = test::ToString(p->program(), ast_body);
513   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<i32> = " + GetParam().wgsl_func +
514                               "(v2i1);"))
515       << body;
516 }
517 
TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting,Scalar)518 TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting, Scalar) {
519   const auto assembly = Preamble() + R"(
520      %1 = OpExtInst %int %glsl )" +
521                         GetParam().opcode +
522                         R"( %i1 %i2
523      OpReturn
524      OpFunctionEnd
525   )";
526   auto p = parser(test::Assemble(assembly));
527   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
528   auto fe = p->function_emitter(100);
529   EXPECT_TRUE(fe.EmitBody()) << p->error();
530   auto ast_body = fe.ast_body();
531   const auto body = test::ToString(p->program(), ast_body);
532   EXPECT_THAT(
533       body, HasSubstr("let x_1 : i32 = " + GetParam().wgsl_func + "(i1, i2);"))
534       << body;
535 }
536 
TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting,Vector)537 TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting, Vector) {
538   const auto assembly = Preamble() + R"(
539      %1 = OpExtInst %v2int %glsl )" +
540                         GetParam().opcode +
541                         R"( %v2i1 %v2i2
542      OpReturn
543      OpFunctionEnd
544   )";
545   auto p = parser(test::Assemble(assembly));
546   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
547   auto fe = p->function_emitter(100);
548   EXPECT_TRUE(fe.EmitBody()) << p->error();
549   auto ast_body = fe.ast_body();
550   const auto body = test::ToString(p->program(), ast_body);
551   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<i32> = " + GetParam().wgsl_func +
552                               "(v2i1, v2i2);"))
553       << body;
554 }
555 
TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting,Scalar)556 TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting, Scalar) {
557   const auto assembly = Preamble() + R"(
558      %1 = OpExtInst %int %glsl )" +
559                         GetParam().opcode +
560                         R"( %i1 %i2 %i3
561      OpReturn
562      OpFunctionEnd
563   )";
564   auto p = parser(test::Assemble(assembly));
565   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
566   auto fe = p->function_emitter(100);
567   EXPECT_TRUE(fe.EmitBody()) << p->error();
568   auto ast_body = fe.ast_body();
569   const auto body = test::ToString(p->program(), ast_body);
570   EXPECT_THAT(body, HasSubstr("let x_1 : i32 = " + GetParam().wgsl_func +
571                               "(i1, i2, i3);"))
572       << body;
573 }
574 
TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting,Vector)575 TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting, Vector) {
576   const auto assembly = Preamble() + R"(
577      %1 = OpExtInst %v2int %glsl )" +
578                         GetParam().opcode +
579                         R"( %v2i1 %v2i2 %v2i3
580      OpReturn
581      OpFunctionEnd
582   )";
583   auto p = parser(test::Assemble(assembly));
584   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
585   auto fe = p->function_emitter(100);
586   EXPECT_TRUE(fe.EmitBody()) << p->error();
587   auto ast_body = fe.ast_body();
588   const auto body = test::ToString(p->program(), ast_body);
589   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<i32> = " + GetParam().wgsl_func +
590                               "(v2i1, v2i2, v2i3);"))
591       << body;
592 }
593 
594 INSTANTIATE_TEST_SUITE_P(Samples,
595                          SpvParserTest_GlslStd450_Inting_Inting,
596                          ::testing::Values(GlslStd450Case{"SAbs", "abs"}));
597 
598 INSTANTIATE_TEST_SUITE_P(Samples,
599                          SpvParserTest_GlslStd450_Inting_IntingInting,
600                          ::testing::Values(GlslStd450Case{"SMax", "max"},
601                                            GlslStd450Case{"SMin", "min"}));
602 
603 INSTANTIATE_TEST_SUITE_P(Samples,
604                          SpvParserTest_GlslStd450_Inting_IntingIntingInting,
605                          ::testing::Values(GlslStd450Case{"SClamp", "clamp"}));
606 
TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting,Scalar)607 TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting, Scalar) {
608   const auto assembly = Preamble() + R"(
609      %1 = OpExtInst %uint %glsl )" +
610                         GetParam().opcode + R"( %u1 %u2
611      OpReturn
612      OpFunctionEnd
613   )";
614   auto p = parser(test::Assemble(assembly));
615   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
616   auto fe = p->function_emitter(100);
617   EXPECT_TRUE(fe.EmitBody()) << p->error();
618   auto ast_body = fe.ast_body();
619   const auto body = test::ToString(p->program(), ast_body);
620   EXPECT_THAT(
621       body, HasSubstr("let x_1 : u32 = " + GetParam().wgsl_func + "(u1, u2);"))
622       << body;
623 }
624 
TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting,Vector)625 TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting, Vector) {
626   const auto assembly = Preamble() + R"(
627      %1 = OpExtInst %v2uint %glsl )" +
628                         GetParam().opcode +
629                         R"( %v2u1 %v2u2
630      OpReturn
631      OpFunctionEnd
632   )";
633   auto p = parser(test::Assemble(assembly));
634   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
635   auto fe = p->function_emitter(100);
636   EXPECT_TRUE(fe.EmitBody()) << p->error();
637   auto ast_body = fe.ast_body();
638   const auto body = test::ToString(p->program(), ast_body);
639   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<u32> = " + GetParam().wgsl_func +
640                               "(v2u1, v2u2);"))
641       << body;
642 }
643 
TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting,Scalar)644 TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting, Scalar) {
645   const auto assembly = Preamble() + R"(
646      %1 = OpExtInst %uint %glsl )" +
647                         GetParam().opcode + R"( %u1 %u2 %u3
648      OpReturn
649      OpFunctionEnd
650   )";
651   auto p = parser(test::Assemble(assembly));
652   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
653   auto fe = p->function_emitter(100);
654   EXPECT_TRUE(fe.EmitBody()) << p->error();
655   auto ast_body = fe.ast_body();
656   const auto body = test::ToString(p->program(), ast_body);
657   EXPECT_THAT(body, HasSubstr("let x_1 : u32 = " + GetParam().wgsl_func +
658                               "(u1, u2, u3);"))
659       << body;
660 }
661 
TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting,Vector)662 TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting, Vector) {
663   const auto assembly = Preamble() + R"(
664      %1 = OpExtInst %v2uint %glsl )" +
665                         GetParam().opcode +
666                         R"( %v2u1 %v2u2 %v2u3
667      OpReturn
668      OpFunctionEnd
669   )";
670   auto p = parser(test::Assemble(assembly));
671   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
672   auto fe = p->function_emitter(100);
673   EXPECT_TRUE(fe.EmitBody()) << p->error();
674   auto ast_body = fe.ast_body();
675   const auto body = test::ToString(p->program(), ast_body);
676   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<u32> = " + GetParam().wgsl_func +
677                               "(v2u1, v2u2, v2u3);"))
678       << body;
679 }
680 
681 INSTANTIATE_TEST_SUITE_P(Samples,
682                          SpvParserTest_GlslStd450_Uinting_UintingUinting,
683                          ::testing::Values(GlslStd450Case{"UMax", "max"},
684                                            GlslStd450Case{"UMin", "min"}));
685 
686 INSTANTIATE_TEST_SUITE_P(Samples,
687                          SpvParserTest_GlslStd450_Uinting_UintingUintingUinting,
688                          ::testing::Values(GlslStd450Case{"UClamp", "clamp"}));
689 
690 // Test Normalize.  WGSL does not have a scalar form of the normalize builtin.
691 // So we have to test it separately, as it does not fit the patterns tested
692 // above.
693 
TEST_F(SpvParserTest,Normalize_Scalar)694 TEST_F(SpvParserTest, Normalize_Scalar) {
695   // Scalar normalize always results in 1.0
696   const auto assembly = Preamble() + R"(
697      %1 = OpExtInst %float %glsl Normalize %f1
698      OpReturn
699      OpFunctionEnd
700   )";
701   auto p = parser(test::Assemble(assembly));
702   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
703   auto fe = p->function_emitter(100);
704   EXPECT_TRUE(fe.EmitBody()) << p->error();
705   auto ast_body = fe.ast_body();
706   const auto body = test::ToString(p->program(), ast_body);
707   EXPECT_THAT(body, HasSubstr("let x_1 : f32 = 1.0;")) << body;
708 }
709 
TEST_F(SpvParserTest,Normalize_Vector2)710 TEST_F(SpvParserTest, Normalize_Vector2) {
711   // Scalar normalize always results in 1.0
712   const auto assembly = Preamble() + R"(
713      %1 = OpExtInst %v2float %glsl Normalize %v2f1
714      OpReturn
715      OpFunctionEnd
716   )";
717   auto p = parser(test::Assemble(assembly));
718   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
719   auto fe = p->function_emitter(100);
720   EXPECT_TRUE(fe.EmitBody()) << p->error();
721   auto ast_body = fe.ast_body();
722   const auto body = test::ToString(p->program(), ast_body);
723   EXPECT_THAT(body, HasSubstr("let x_1 : vec2<f32> = normalize(v2f1);"))
724       << body;
725 }
726 
TEST_F(SpvParserTest,Normalize_Vector3)727 TEST_F(SpvParserTest, Normalize_Vector3) {
728   // Scalar normalize always results in 1.0
729   const auto assembly = Preamble() + R"(
730      %1 = OpExtInst %v3float %glsl Normalize %v3f1
731      OpReturn
732      OpFunctionEnd
733   )";
734   auto p = parser(test::Assemble(assembly));
735   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
736   auto fe = p->function_emitter(100);
737   EXPECT_TRUE(fe.EmitBody()) << p->error();
738   auto ast_body = fe.ast_body();
739   const auto body = test::ToString(p->program(), ast_body);
740   EXPECT_THAT(body, HasSubstr("let x_1 : vec3<f32> = normalize(v3f1);"))
741       << body;
742 }
743 
TEST_F(SpvParserTest,Normalize_Vector4)744 TEST_F(SpvParserTest, Normalize_Vector4) {
745   // Scalar normalize always results in 1.0
746   const auto assembly = Preamble() + R"(
747      %1 = OpExtInst %v4float %glsl Normalize %v4f1
748      OpReturn
749      OpFunctionEnd
750   )";
751   auto p = parser(test::Assemble(assembly));
752   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
753   auto fe = p->function_emitter(100);
754   EXPECT_TRUE(fe.EmitBody()) << p->error();
755   auto ast_body = fe.ast_body();
756   const auto body = test::ToString(p->program(), ast_body);
757   EXPECT_THAT(body, HasSubstr("let x_1 : vec4<f32> = normalize(v4f1);"))
758       << body;
759 }
760 
761 // Check that we convert signedness of operands and result type.
762 // This is needed for each of the integer-based extended instructions.
763 
TEST_F(SpvParserTest,RectifyOperandsAndResult_SAbs)764 TEST_F(SpvParserTest, RectifyOperandsAndResult_SAbs) {
765   const auto assembly = Preamble() + R"(
766      %1 = OpExtInst %uint %glsl SAbs %u1
767      %2 = OpExtInst %v2uint %glsl SAbs %v2u1
768      OpReturn
769      OpFunctionEnd
770   )";
771   auto p = parser(test::Assemble(assembly));
772   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
773   auto fe = p->function_emitter(100);
774   EXPECT_TRUE(fe.EmitBody()) << p->error();
775   auto ast_body = fe.ast_body();
776   const auto body = test::ToString(p->program(), ast_body);
777   EXPECT_THAT(
778       body,
779       HasSubstr(R"(let x_1 : u32 = bitcast<u32>(abs(bitcast<i32>(u1)));)"))
780       << body;
781   EXPECT_THAT(
782       body,
783       HasSubstr(
784           R"(let x_2 : vec2<u32> = bitcast<vec2<u32>>(abs(bitcast<vec2<i32>>(v2u1)));)"))
785       << body;
786 }
787 
TEST_F(SpvParserTest,RectifyOperandsAndResult_SMax)788 TEST_F(SpvParserTest, RectifyOperandsAndResult_SMax) {
789   const auto assembly = Preamble() + R"(
790      %1 = OpExtInst %uint %glsl SMax %u1 %u2
791      %2 = OpExtInst %v2uint %glsl SMax %v2u1 %v2u2
792      OpReturn
793      OpFunctionEnd
794   )";
795   auto p = parser(test::Assemble(assembly));
796   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
797   auto fe = p->function_emitter(100);
798   EXPECT_TRUE(fe.EmitBody()) << p->error();
799   auto ast_body = fe.ast_body();
800   auto body = test::ToString(p->program(), ast_body);
801   EXPECT_THAT(
802       body,
803       HasSubstr(
804           R"(let x_1 : u32 = bitcast<u32>(max(bitcast<i32>(u1), bitcast<i32>(u2)));)"))
805       << body;
806   EXPECT_THAT(
807       body,
808       HasSubstr(
809           R"(let x_2 : vec2<u32> = bitcast<vec2<u32>>(max(bitcast<vec2<i32>>(v2u1), bitcast<vec2<i32>>(v2u2)));)"))
810       << body;
811 }
812 
TEST_F(SpvParserTest,RectifyOperandsAndResult_SMin)813 TEST_F(SpvParserTest, RectifyOperandsAndResult_SMin) {
814   const auto assembly = Preamble() + R"(
815      %1 = OpExtInst %uint %glsl SMin %u1 %u2
816      %2 = OpExtInst %v2uint %glsl SMin %v2u1 %v2u2
817      OpReturn
818      OpFunctionEnd
819   )";
820   auto p = parser(test::Assemble(assembly));
821   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
822   auto fe = p->function_emitter(100);
823   EXPECT_TRUE(fe.EmitBody()) << p->error();
824   auto ast_body = fe.ast_body();
825   auto body = test::ToString(p->program(), ast_body);
826   EXPECT_THAT(
827       body,
828       HasSubstr(
829           R"(let x_1 : u32 = bitcast<u32>(min(bitcast<i32>(u1), bitcast<i32>(u2)));)"))
830       << body;
831   EXPECT_THAT(
832       body,
833       HasSubstr(
834           R"(let x_2 : vec2<u32> = bitcast<vec2<u32>>(min(bitcast<vec2<i32>>(v2u1), bitcast<vec2<i32>>(v2u2)));)"))
835       << body;
836 }
837 
TEST_F(SpvParserTest,RectifyOperandsAndResult_SClamp)838 TEST_F(SpvParserTest, RectifyOperandsAndResult_SClamp) {
839   const auto assembly = Preamble() + R"(
840      %1 = OpExtInst %uint %glsl SClamp %u1 %i2 %u3
841      %2 = OpExtInst %v2uint %glsl SClamp %v2u1 %v2i2 %v2u3
842      OpReturn
843      OpFunctionEnd
844   )";
845   auto p = parser(test::Assemble(assembly));
846   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
847   auto fe = p->function_emitter(100);
848   EXPECT_TRUE(fe.EmitBody()) << p->error();
849   auto ast_body = fe.ast_body();
850   auto body = test::ToString(p->program(), ast_body);
851   EXPECT_THAT(
852       body,
853       HasSubstr(
854           R"(let x_1 : u32 = bitcast<u32>(clamp(bitcast<i32>(u1), i2, bitcast<i32>(u3)));)"))
855       << body;
856   EXPECT_THAT(
857       body,
858       HasSubstr(
859           R"(let x_2 : vec2<u32> = bitcast<vec2<u32>>(clamp(bitcast<vec2<i32>>(v2u1), v2i2, bitcast<vec2<i32>>(v2u3)));)"))
860       << body;
861 }
862 
TEST_F(SpvParserTest,RectifyOperandsAndResult_UMax)863 TEST_F(SpvParserTest, RectifyOperandsAndResult_UMax) {
864   const auto assembly = Preamble() + R"(
865      %1 = OpExtInst %int %glsl UMax %i1 %i2
866      %2 = OpExtInst %v2int %glsl UMax %v2i1 %v2i2
867      OpReturn
868      OpFunctionEnd
869   )";
870   auto p = parser(test::Assemble(assembly));
871   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
872   auto fe = p->function_emitter(100);
873   EXPECT_TRUE(fe.EmitBody()) << p->error();
874   auto ast_body = fe.ast_body();
875   auto body = test::ToString(p->program(), ast_body);
876   EXPECT_THAT(
877       body,
878       HasSubstr(
879           R"(let x_1 : i32 = bitcast<i32>(max(bitcast<u32>(i1), bitcast<u32>(i2)));)"))
880       << body;
881   EXPECT_THAT(
882       body,
883       HasSubstr(
884           R"(let x_2 : vec2<i32> = bitcast<vec2<i32>>(max(bitcast<vec2<u32>>(v2i1), bitcast<vec2<u32>>(v2i2)));)"))
885       << body;
886 }
887 
TEST_F(SpvParserTest,RectifyOperandsAndResult_UMin)888 TEST_F(SpvParserTest, RectifyOperandsAndResult_UMin) {
889   const auto assembly = Preamble() + R"(
890      %1 = OpExtInst %int %glsl UMin %i1 %i2
891      %2 = OpExtInst %v2int %glsl UMin %v2i1 %v2i2
892      OpReturn
893      OpFunctionEnd
894   )";
895   auto p = parser(test::Assemble(assembly));
896   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
897   auto fe = p->function_emitter(100);
898   EXPECT_TRUE(fe.EmitBody()) << p->error();
899   auto ast_body = fe.ast_body();
900   auto body = test::ToString(p->program(), ast_body);
901   EXPECT_THAT(
902       body,
903       HasSubstr(
904           R"(let x_1 : i32 = bitcast<i32>(min(bitcast<u32>(i1), bitcast<u32>(i2)));)"))
905       << body;
906   EXPECT_THAT(
907       body,
908       HasSubstr(
909           R"(let x_2 : vec2<i32> = bitcast<vec2<i32>>(min(bitcast<vec2<u32>>(v2i1), bitcast<vec2<u32>>(v2i2)));)"))
910       << body;
911 }
912 
TEST_F(SpvParserTest,RectifyOperandsAndResult_UClamp)913 TEST_F(SpvParserTest, RectifyOperandsAndResult_UClamp) {
914   const auto assembly = Preamble() + R"(
915      %1 = OpExtInst %int %glsl UClamp %i1 %u2 %i3
916      %2 = OpExtInst %v2int %glsl UClamp %v2i1 %v2u2 %v2i3
917      OpReturn
918      OpFunctionEnd
919   )";
920   auto p = parser(test::Assemble(assembly));
921   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
922   auto fe = p->function_emitter(100);
923   EXPECT_TRUE(fe.EmitBody()) << p->error();
924   auto ast_body = fe.ast_body();
925   auto body = test::ToString(p->program(), ast_body);
926   EXPECT_THAT(
927       body,
928       HasSubstr(
929           R"(let x_1 : i32 = bitcast<i32>(clamp(bitcast<u32>(i1), u2, bitcast<u32>(i3)));)"))
930       << body;
931   EXPECT_THAT(
932       body,
933       HasSubstr(
934           R"(let x_2 : vec2<i32> = bitcast<vec2<i32>>(clamp(bitcast<vec2<u32>>(v2i1), v2u2, bitcast<vec2<u32>>(v2i3)));)"))
935       << body;
936 }
937 
938 struct DataPackingCase {
939   std::string opcode;
940   std::string wgsl_func;
941   uint32_t vec_size;
942 };
943 
operator <<(std::ostream & out,DataPackingCase c)944 inline std::ostream& operator<<(std::ostream& out, DataPackingCase c) {
945   out << "DataPacking(" << c.opcode << ")";
946   return out;
947 }
948 
949 using SpvParserTest_GlslStd450_DataPacking =
950     SpvParserTestBase<::testing::TestWithParam<DataPackingCase>>;
951 
TEST_P(SpvParserTest_GlslStd450_DataPacking,Valid)952 TEST_P(SpvParserTest_GlslStd450_DataPacking, Valid) {
953   auto param = GetParam();
954   const auto assembly = Preamble() + R"(
955   %1 = OpExtInst %uint %glsl )" +
956                         param.opcode +
957                         (param.vec_size == 2 ? " %v2f1" : " %v4f1") + R"(
958   OpReturn
959   OpFunctionEnd
960   )";
961   auto p = parser(test::Assemble(assembly));
962   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
963   auto fe = p->function_emitter(100);
964   EXPECT_TRUE(fe.EmitBody()) << p->error();
965   auto ast_body = fe.ast_body();
966   const auto body = test::ToString(p->program(), ast_body);
967   EXPECT_THAT(body, HasSubstr("let x_1 : u32 = " + param.wgsl_func + "(v" +
968                               std::to_string(param.vec_size) + "f1);"))
969       << body;
970 }
971 
972 INSTANTIATE_TEST_SUITE_P(Samples,
973                          SpvParserTest_GlslStd450_DataPacking,
974                          ::testing::ValuesIn(std::vector<DataPackingCase>{
975                              {"PackSnorm4x8", "pack4x8snorm", 4},
976                              {"PackUnorm4x8", "pack4x8unorm", 4},
977                              {"PackSnorm2x16", "pack2x16snorm", 2},
978                              {"PackUnorm2x16", "pack2x16unorm", 2},
979                              {"PackHalf2x16", "pack2x16float", 2}}));
980 
981 using SpvParserTest_GlslStd450_DataUnpacking =
982     SpvParserTestBase<::testing::TestWithParam<DataPackingCase>>;
983 
TEST_P(SpvParserTest_GlslStd450_DataUnpacking,Valid)984 TEST_P(SpvParserTest_GlslStd450_DataUnpacking, Valid) {
985   auto param = GetParam();
986   const auto assembly = Preamble() + R"(
987   %1 = OpExtInst )" + (param.vec_size == 2 ? "%v2float" : "%v4float") +
988                         std::string(" %glsl ") + param.opcode + R"( %u1
989   OpReturn
990   OpFunctionEnd
991   )";
992   auto p = parser(test::Assemble(assembly));
993   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << assembly;
994   auto fe = p->function_emitter(100);
995   EXPECT_TRUE(fe.EmitBody()) << p->error();
996   auto ast_body = fe.ast_body();
997   const auto body = test::ToString(p->program(), ast_body);
998   EXPECT_THAT(body, HasSubstr("let x_1 : " +
999                               std::string(param.vec_size == 2 ? "vec2<f32>"
1000                                                               : "vec4<f32>") +
1001 
1002                               +" = " + param.wgsl_func + "(u1);"))
1003       << body;
1004 }
1005 
1006 INSTANTIATE_TEST_SUITE_P(Samples,
1007                          SpvParserTest_GlslStd450_DataUnpacking,
1008                          ::testing::ValuesIn(std::vector<DataPackingCase>{
1009                              {"UnpackSnorm4x8", "unpack4x8snorm", 4},
1010                              {"UnpackUnorm4x8", "unpack4x8unorm", 4},
1011                              {"UnpackSnorm2x16", "unpack2x16snorm", 2},
1012                              {"UnpackUnorm2x16", "unpack2x16unorm", 2},
1013                              {"UnpackHalf2x16", "unpack2x16float", 2}}));
1014 
TEST_F(SpvParserTest,GlslStd450_Refract_Scalar)1015 TEST_F(SpvParserTest, GlslStd450_Refract_Scalar) {
1016   const auto assembly = Preamble() + R"(
1017      %1 = OpExtInst %float %glsl Refract %f1 %f2 %f3
1018      OpReturn
1019      OpFunctionEnd
1020   )";
1021   auto p = parser(test::Assemble(assembly));
1022   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1023   auto fe = p->function_emitter(100);
1024   EXPECT_TRUE(fe.EmitBody()) << p->error();
1025   auto ast_body = fe.ast_body();
1026   const auto body = test::ToString(p->program(), ast_body);
1027   const auto* expected =
1028       R"(let x_1 : f32 = refract(vec2<f32>(f1, 0.0), vec2<f32>(f2, 0.0), f3).x;)";
1029 
1030   EXPECT_THAT(body, HasSubstr(expected)) << body;
1031 }
1032 
TEST_F(SpvParserTest,GlslStd450_Refract_Vector)1033 TEST_F(SpvParserTest, GlslStd450_Refract_Vector) {
1034   const auto assembly = Preamble() + R"(
1035      %1 = OpExtInst %v2float %glsl Refract %v2f1 %v2f2 %f3
1036      OpReturn
1037      OpFunctionEnd
1038   )";
1039   auto p = parser(test::Assemble(assembly));
1040   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1041   auto fe = p->function_emitter(100);
1042   EXPECT_TRUE(fe.EmitBody()) << p->error();
1043   auto ast_body = fe.ast_body();
1044   const auto body = test::ToString(p->program(), ast_body);
1045   const auto* expected = R"(let x_1 : vec2<f32> = refract(v2f1, v2f2, f3);)";
1046 
1047   EXPECT_THAT(body, HasSubstr(expected)) << body;
1048 }
1049 
TEST_F(SpvParserTest,GlslStd450_FaceForward_Scalar)1050 TEST_F(SpvParserTest, GlslStd450_FaceForward_Scalar) {
1051   const auto assembly = Preamble() + R"(
1052      %99 = OpFAdd %float %f1 %f1 ; normal operand has only one use
1053      %1 = OpExtInst %float %glsl FaceForward %99 %f2 %f3
1054      OpReturn
1055      OpFunctionEnd
1056   )";
1057   auto p = parser(test::Assemble(assembly));
1058   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1059   auto fe = p->function_emitter(100);
1060   EXPECT_TRUE(fe.EmitBody()) << p->error();
1061   auto ast_body = fe.ast_body();
1062   const auto body = test::ToString(p->program(), ast_body);
1063   // The %99 sum only has one use.  Ensure it is evaluated only once by
1064   // making a let-declaration for it, since it is the normal operand to
1065   // the builtin function, and code generation uses it twice.
1066   const auto* expected =
1067       R"(let x_1 : f32 = select(-(x_99), x_99, ((f2 * f3) < 0.0));)";
1068 
1069   EXPECT_THAT(body, HasSubstr(expected)) << body;
1070 }
1071 
TEST_F(SpvParserTest,GlslStd450_FaceForward_Vector)1072 TEST_F(SpvParserTest, GlslStd450_FaceForward_Vector) {
1073   const auto assembly = Preamble() + R"(
1074      %99 = OpFAdd %v2float %v2f1 %v2f1
1075      %1 = OpExtInst %v2float %glsl FaceForward %v2f1 %v2f2 %v2f3
1076      OpReturn
1077      OpFunctionEnd
1078   )";
1079   auto p = parser(test::Assemble(assembly));
1080   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1081   auto fe = p->function_emitter(100);
1082   EXPECT_TRUE(fe.EmitBody()) << p->error();
1083   auto ast_body = fe.ast_body();
1084   const auto body = test::ToString(p->program(), ast_body);
1085   const auto* expected =
1086       R"(let x_1 : vec2<f32> = faceForward(v2f1, v2f2, v2f3);)";
1087 
1088   EXPECT_THAT(body, HasSubstr(expected)) << body;
1089 }
1090 
TEST_F(SpvParserTest,GlslStd450_Reflect_Scalar)1091 TEST_F(SpvParserTest, GlslStd450_Reflect_Scalar) {
1092   const auto assembly = Preamble() + R"(
1093      %98 = OpFAdd %float %f1 %f1 ; has only one use
1094      %99 = OpFAdd %float %f2 %f2 ; has only one use
1095      %1 = OpExtInst %float %glsl Reflect %98 %99
1096      OpReturn
1097      OpFunctionEnd
1098   )";
1099   auto p = parser(test::Assemble(assembly));
1100   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1101   auto fe = p->function_emitter(100);
1102   EXPECT_TRUE(fe.EmitBody()) << p->error();
1103   auto ast_body = fe.ast_body();
1104   const auto body = test::ToString(p->program(), ast_body);
1105   // The %99 sum only has one use.  Ensure it is evaluated only once by
1106   // making a let-declaration for it, since it is the normal operand to
1107   // the builtin function, and code generation uses it twice.
1108   const auto* expected =
1109       R"(let x_1 : f32 = (x_98 - (2.0 * (x_99 * (x_99 * x_98))));)";
1110 
1111   EXPECT_THAT(body, HasSubstr(expected)) << body;
1112 }
1113 
TEST_F(SpvParserTest,GlslStd450_Reflect_Vector)1114 TEST_F(SpvParserTest, GlslStd450_Reflect_Vector) {
1115   const auto assembly = Preamble() + R"(
1116      %98 = OpFAdd %v2float %v2f1 %v2f1
1117      %99 = OpFAdd %v2float %v2f2 %v2f2
1118      %1 = OpExtInst %v2float %glsl Reflect %98 %99
1119      OpReturn
1120      OpFunctionEnd
1121   )";
1122   auto p = parser(test::Assemble(assembly));
1123   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1124   auto fe = p->function_emitter(100);
1125   EXPECT_TRUE(fe.EmitBody()) << p->error();
1126   auto ast_body = fe.ast_body();
1127   const auto body = test::ToString(p->program(), ast_body);
1128   const auto* expected = R"(
1129 let x_98 : vec2<f32> = (v2f1 + v2f1);
1130 let x_99 : vec2<f32> = (v2f2 + v2f2);
1131 let x_1 : vec2<f32> = reflect(x_98, x_99);
1132 )";
1133 
1134   EXPECT_THAT(body, HasSubstr(expected)) << body;
1135 }
1136 
TEST_F(SpvParserTest,GlslStd450_Degrees_Scalar)1137 TEST_F(SpvParserTest, GlslStd450_Degrees_Scalar) {
1138   const auto assembly = Preamble() + R"(
1139      %1 = OpExtInst %float %glsl Degrees %float_50
1140      OpReturn
1141      OpFunctionEnd
1142   )";
1143   auto p = parser(test::Assemble(assembly));
1144   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1145   auto fe = p->function_emitter(100);
1146   EXPECT_TRUE(fe.EmitBody()) << p->error();
1147   auto ast_body = fe.ast_body();
1148   const auto body = test::ToString(p->program(), ast_body);
1149   const auto* expected = "let x_1 : f32 = (50.0 * 57.295780182);";
1150 
1151   EXPECT_THAT(body, HasSubstr(expected)) << body;
1152 }
1153 
TEST_F(SpvParserTest,GlslStd450_Degrees_Vector)1154 TEST_F(SpvParserTest, GlslStd450_Degrees_Vector) {
1155   const auto assembly = Preamble() + R"(
1156      %1 = OpExtInst %v3float %glsl Degrees %v3float_60_70_50
1157      OpReturn
1158      OpFunctionEnd
1159   )";
1160   auto p = parser(test::Assemble(assembly));
1161   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1162   auto fe = p->function_emitter(100);
1163   EXPECT_TRUE(fe.EmitBody()) << p->error();
1164   auto ast_body = fe.ast_body();
1165   const auto body = test::ToString(p->program(), ast_body);
1166   const auto* expected =
1167       R"(let x_1 : vec3<f32> = (vec3<f32>(60.0, 70.0, 50.0) * vec3<f32>(57.295780182));)";
1168 
1169   EXPECT_THAT(body, HasSubstr(expected)) << body;
1170 }
1171 
TEST_F(SpvParserTest,GlslStd450_Radians_Scalar)1172 TEST_F(SpvParserTest, GlslStd450_Radians_Scalar) {
1173   const auto assembly = Preamble() + R"(
1174      %1 = OpExtInst %float %glsl Radians %float_50
1175      OpReturn
1176      OpFunctionEnd
1177   )";
1178   auto p = parser(test::Assemble(assembly));
1179   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1180   auto fe = p->function_emitter(100);
1181   EXPECT_TRUE(fe.EmitBody()) << p->error();
1182   auto ast_body = fe.ast_body();
1183   const auto body = test::ToString(p->program(), ast_body);
1184   const auto* expected = "let x_1 : f32 = (50.0 * 0.017453292);";
1185 
1186   EXPECT_THAT(body, HasSubstr(expected)) << body;
1187 }
1188 
TEST_F(SpvParserTest,GlslStd450_Radians_Vector)1189 TEST_F(SpvParserTest, GlslStd450_Radians_Vector) {
1190   const auto assembly = Preamble() + R"(
1191      %1 = OpExtInst %v3float %glsl Radians %v3float_60_70_50
1192      OpReturn
1193      OpFunctionEnd
1194   )";
1195   auto p = parser(test::Assemble(assembly));
1196   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1197   auto fe = p->function_emitter(100);
1198   EXPECT_TRUE(fe.EmitBody()) << p->error();
1199   auto ast_body = fe.ast_body();
1200   const auto body = test::ToString(p->program(), ast_body);
1201   const auto* expected =
1202       R"(let x_1 : vec3<f32> = (vec3<f32>(60.0, 70.0, 50.0) * vec3<f32>(0.017453292));)";
1203 
1204   EXPECT_THAT(body, HasSubstr(expected)) << body;
1205 }
1206 
1207 // For ldexp with signed second argument, see above.
TEST_F(SpvParserTest,GlslStd450_Ldexp_Scalar_Float_Uint)1208 TEST_F(SpvParserTest, GlslStd450_Ldexp_Scalar_Float_Uint) {
1209   const auto assembly = Preamble() + R"(
1210      %1 = OpExtInst %float %glsl Ldexp %f1 %u1
1211      OpReturn
1212      OpFunctionEnd
1213   )";
1214   auto p = parser(test::Assemble(assembly));
1215   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1216   auto fe = p->function_emitter(100);
1217   EXPECT_TRUE(fe.EmitBody()) << p->error();
1218   auto ast_body = fe.ast_body();
1219   const auto body = test::ToString(p->program(), ast_body);
1220   const auto* expected = "let x_1 : f32 = ldexp(f1, i32(u1));";
1221 
1222   EXPECT_THAT(body, HasSubstr(expected)) << body;
1223 }
1224 
TEST_F(SpvParserTest,GlslStd450_Ldexp_Vector_Floatvec_Uintvec)1225 TEST_F(SpvParserTest, GlslStd450_Ldexp_Vector_Floatvec_Uintvec) {
1226   const auto assembly = Preamble() + R"(
1227      %1 = OpExtInst %v2float %glsl Ldexp %v2f1 %v2u1
1228      OpReturn
1229      OpFunctionEnd
1230   )";
1231   auto p = parser(test::Assemble(assembly));
1232   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
1233   auto fe = p->function_emitter(100);
1234   EXPECT_TRUE(fe.EmitBody()) << p->error();
1235   auto ast_body = fe.ast_body();
1236   const auto body = test::ToString(p->program(), ast_body);
1237   const auto* expected = "let x_1 : vec2<f32> = ldexp(v2f1, vec2<i32>(v2u1));";
1238 
1239   EXPECT_THAT(body, HasSubstr(expected)) << body;
1240 }
1241 
1242 }  // namespace
1243 }  // namespace spirv
1244 }  // namespace reader
1245 }  // namespace tint
1246