• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // MSLOutput_test.cpp:
7 //   Tests for MSL output.
8 //
9 
10 #include <regex>
11 #include "GLSLANG/ShaderLang.h"
12 #include "angle_gl.h"
13 #include "gtest/gtest.h"
14 #include "tests/test_utils/compiler_test.h"
15 
16 using namespace sh;
17 
18 class MSLVertexOutputTest : public MatchOutputCodeTest
19 {
20   public:
MSLVertexOutputTest()21     MSLVertexOutputTest() : MatchOutputCodeTest(GL_VERTEX_SHADER, 0, SH_MSL_METAL_OUTPUT) {}
22 };
23 
24 class MSLOutputTest : public MatchOutputCodeTest
25 {
26   public:
MSLOutputTest()27     MSLOutputTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, 0, SH_MSL_METAL_OUTPUT) {}
28 };
29 
30 // Test that having dynamic indexing of a vector inside the right hand side of logical or doesn't
31 // trigger asserts in MSL output.
TEST_F(MSLOutputTest,DynamicIndexingOfVectorOnRightSideOfLogicalOr)32 TEST_F(MSLOutputTest, DynamicIndexingOfVectorOnRightSideOfLogicalOr)
33 {
34     const std::string &shaderString =
35         "#version 300 es\n"
36         "precision highp float;\n"
37         "out vec4 my_FragColor;\n"
38         "uniform int u1;\n"
39         "void main() {\n"
40         "   bvec4 v = bvec4(true, true, true, false);\n"
41         "   my_FragColor = vec4(v[u1 + 1] || v[u1]);\n"
42         "}\n";
43     compile(shaderString, SH_VARIABLES);
44 }
45 
46 // Test that having an array constructor as a statement doesn't trigger an assert in MSL output.
TEST_F(MSLOutputTest,ArrayConstructorStatement)47 TEST_F(MSLOutputTest, ArrayConstructorStatement)
48 {
49     const std::string &shaderString =
50         R"(#version 300 es
51         precision mediump float;
52         out vec4 outColor;
53         void main()
54         {
55             outColor = vec4(0.0, 0.0, 0.0, 1.0);
56             float[1](outColor[1]++);
57         })";
58     compile(shaderString, SH_VARIABLES);
59 }
60 
61 // Test an array of arrays constructor as a statement.
TEST_F(MSLOutputTest,ArrayOfArraysStatement)62 TEST_F(MSLOutputTest, ArrayOfArraysStatement)
63 {
64     const std::string &shaderString =
65         R"(#version 310 es
66         precision mediump float;
67         out vec4 outColor;
68         void main()
69         {
70             outColor = vec4(0.0, 0.0, 0.0, 1.0);
71             float[2][2](float[2](outColor[1]++, 0.0), float[2](1.0, 2.0));
72         })";
73     compile(shaderString, SH_VARIABLES);
74 }
75 
76 // Test dynamic indexing of a vector. This makes sure that helper functions added for dynamic
77 // indexing have correct data that subsequent traversal steps rely on.
TEST_F(MSLOutputTest,VectorDynamicIndexing)78 TEST_F(MSLOutputTest, VectorDynamicIndexing)
79 {
80     const std::string &shaderString =
81         R"(#version 300 es
82         precision mediump float;
83         out vec4 outColor;
84         uniform int i;
85         void main()
86         {
87             vec4 foo = vec4(0.0, 0.0, 0.0, 1.0);
88             foo[i] = foo[i + 1];
89             outColor = foo;
90         })";
91     compile(shaderString, SH_VARIABLES);
92 }
93 
94 // Test returning an array from a user-defined function. This makes sure that function symbols are
95 // changed consistently when the user-defined function is changed to have an array out parameter.
TEST_F(MSLOutputTest,ArrayReturnValue)96 TEST_F(MSLOutputTest, ArrayReturnValue)
97 {
98     const std::string &shaderString =
99         R"(#version 300 es
100         precision mediump float;
101         uniform float u;
102         out vec4 outColor;
103 
104         float[2] getArray(float f)
105         {
106             return float[2](f, f + 1.0);
107         }
108 
109         void main()
110         {
111             float[2] arr = getArray(u);
112             outColor = vec4(arr[0], arr[1], 0.0, 1.0);
113         })";
114     compile(shaderString, SH_VARIABLES);
115 }
116 
117 // Test that writing parameters without a name doesn't assert.
TEST_F(MSLOutputTest,ParameterWithNoName)118 TEST_F(MSLOutputTest, ParameterWithNoName)
119 {
120     const std::string &shaderString =
121         R"(precision mediump float;
122 
123         uniform vec4 v;
124 
125         vec4 s(vec4)
126         {
127             return v;
128         }
129         void main()
130         {
131             gl_FragColor = s(v);
132         })";
133     compile(shaderString, SH_VARIABLES);
134 }
135 
TEST_F(MSLOutputTest,Macro)136 TEST_F(MSLOutputTest, Macro)
137 {
138     const std::string &shaderString =
139         R"(#version 300 es
140         precision highp float;
141 
142         #define FOO vec4
143 
144         out vec4 outColor;
145 
146         void main()
147         {
148             outColor = FOO(1.0, 2.0, 3.0, 4.0);
149         })";
150     compile(shaderString, SH_VARIABLES);
151 }
152 
TEST_F(MSLOutputTest,UniformSimple)153 TEST_F(MSLOutputTest, UniformSimple)
154 {
155     const std::string &shaderString =
156         R"(#version 300 es
157         precision highp float;
158 
159         out vec4 outColor;
160         uniform float x;
161 
162         void main()
163         {
164             outColor = vec4(x, x, x, x);
165         })";
166     compile(shaderString, SH_VARIABLES);
167 }
168 
TEST_F(MSLOutputTest,FragmentOutSimple)169 TEST_F(MSLOutputTest, FragmentOutSimple)
170 {
171     const std::string &shaderString =
172         R"(#version 300 es
173         precision highp float;
174 
175         out vec4 outColor;
176 
177         void main()
178         {
179             outColor = vec4(1.0, 2.0, 3.0, 4.0);
180         })";
181     compile(shaderString, SH_VARIABLES);
182 }
183 
TEST_F(MSLOutputTest,FragmentOutIndirect1)184 TEST_F(MSLOutputTest, FragmentOutIndirect1)
185 {
186     const std::string &shaderString =
187         R"(#version 300 es
188         precision highp float;
189 
190         out vec4 outColor;
191 
192         void foo()
193         {
194             outColor = vec4(1.0, 2.0, 3.0, 4.0);
195         }
196 
197         void bar()
198         {
199             foo();
200         }
201 
202         void main()
203         {
204             bar();
205         })";
206     compile(shaderString, SH_VARIABLES);
207 }
208 
TEST_F(MSLOutputTest,FragmentOutIndirect2)209 TEST_F(MSLOutputTest, FragmentOutIndirect2)
210 {
211     const std::string &shaderString =
212         R"(#version 300 es
213         precision highp float;
214 
215         out vec4 outColor;
216 
217         void foo();
218 
219         void bar()
220         {
221             foo();
222         }
223 
224         void foo()
225         {
226             outColor = vec4(1.0, 2.0, 3.0, 4.0);
227         }
228 
229         void main()
230         {
231             bar();
232         })";
233     compile(shaderString, SH_VARIABLES);
234 }
235 
TEST_F(MSLOutputTest,FragmentOutIndirect3)236 TEST_F(MSLOutputTest, FragmentOutIndirect3)
237 {
238     const std::string &shaderString =
239         R"(#version 300 es
240         precision highp float;
241 
242         out vec4 outColor;
243 
244         float foo(float x, float y)
245         {
246             outColor = vec4(x, y, 3.0, 4.0);
247             return 7.0;
248         }
249 
250         float bar(float x)
251         {
252             return foo(x, 2.0);
253         }
254 
255         float baz()
256         {
257             return 13.0;
258         }
259 
260         float identity(float x)
261         {
262             return x;
263         }
264 
265         void main()
266         {
267             identity(bar(baz()));
268         })";
269     compile(shaderString, SH_VARIABLES);
270 }
271 
TEST_F(MSLOutputTest,VertexInOut)272 TEST_F(MSLOutputTest, VertexInOut)
273 {
274     const std::string &shaderString =
275         R"(#version 300 es
276         precision highp float;
277         in float in0;
278         out float out0;
279         void main()
280         {
281             out0 = in0;
282         })";
283     compile(shaderString, SH_VARIABLES);
284 }
285 
TEST_F(MSLOutputTest,SymbolSharing)286 TEST_F(MSLOutputTest, SymbolSharing)
287 {
288     const std::string &shaderString =
289         R"(#version 300 es
290         precision highp float;
291 
292         out vec4 outColor;
293 
294         struct Foo {
295             float x;
296             float y;
297         };
298 
299         void doFoo(Foo foo, float zw);
300 
301         void doFoo(Foo foo, float zw)
302         {
303             foo.x = foo.y;
304             outColor = vec4(foo.x, foo.y, zw, zw);
305         }
306 
307         void main()
308         {
309             Foo foo;
310             foo.x = 2.0;
311             foo.y = 2.0;
312             doFoo(foo, 3.0);
313         })";
314     compile(shaderString, SH_VARIABLES);
315 }
316 
TEST_F(MSLOutputTest,StructDecl)317 TEST_F(MSLOutputTest, StructDecl)
318 {
319     const std::string &shaderString =
320         R"(#version 300 es
321         precision highp float;
322 
323         out float out0;
324 
325         struct Foo {
326             float value;
327         };
328 
329         void main()
330         {
331             Foo foo;
332             out0 = foo.value;
333         }
334         )";
335     compile(shaderString, SH_VARIABLES);
336 }
337 
TEST_F(MSLOutputTest,Structs)338 TEST_F(MSLOutputTest, Structs)
339 {
340     const std::string &shaderString =
341         R"(#version 300 es
342         precision highp float;
343 
344         struct Foo {
345             float value;
346         };
347 
348         out vec4 out0;
349 
350         struct Bar {
351             Foo foo;
352         };
353 
354         void go();
355 
356         uniform UniInstance {
357             Bar bar;
358             float instance;
359         } uniInstance;
360 
361         uniform UniGlobal {
362             Foo foo;
363             float global;
364         };
365 
366         void main()
367         {
368             go();
369         }
370 
371         struct Baz {
372             Bar bar;
373         } baz;
374 
375         void go()
376         {
377             out0.x = baz.bar.foo.value;
378             out0.y = global;
379             out0.z = uniInstance.instance;
380             out0.w = 0.0;
381         }
382 
383         )";
384     compile(shaderString, SH_VARIABLES);
385 }
386 
TEST_F(MSLOutputTest,KeywordConflict)387 TEST_F(MSLOutputTest, KeywordConflict)
388 {
389     const std::string &shaderString =
390         R"(#version 300 es
391             precision highp float;
392 
393         struct fragment {
394             float kernel;
395         } device;
396 
397         struct Foo {
398             fragment frag;
399         } foo;
400 
401         out float vertex;
402         float kernel;
403 
404         float stage_in(float x)
405         {
406             return x;
407         }
408 
409         void metal(float metal, float fragment);
410         void metal(float metal, float fragment)
411         {
412             vertex = metal * fragment * foo.frag.kernel;
413         }
414 
415         void main()
416         {
417             metal(stage_in(stage_in(kernel * device.kernel)), foo.frag.kernel);
418         })";
419     compile(shaderString, SH_VARIABLES);
420 }
421 
TEST_F(MSLVertexOutputTest,Vertex)422 TEST_F(MSLVertexOutputTest, Vertex)
423 {
424     const std::string &shaderString =
425         R"(#version 300 es
426         precision highp float;
427         void main()
428         {
429             gl_Position = vec4(1.0,1.0,1.0,1.0);
430         })";
431     compile(shaderString, SH_VARIABLES);
432 }
433 
TEST_F(MSLVertexOutputTest,LastReturn)434 TEST_F(MSLVertexOutputTest, LastReturn)
435 {
436     const std::string &shaderString =
437         R"(#version 300 es
438         in highp vec4 a_position;
439         in highp vec4 a_coords;
440         out highp vec4 v_color;
441 
442         void main (void)
443         {
444             gl_Position = a_position;
445             v_color = vec4(a_coords.xyz, 1.0);
446             return;
447         })";
448     compile(shaderString, SH_VARIABLES);
449 }
450 
TEST_F(MSLOutputTest,LastReturn)451 TEST_F(MSLOutputTest, LastReturn)
452 {
453     const std::string &shaderString =
454         R"(#version 300 es
455         in mediump vec4 v_coords;
456         layout(location = 0) out mediump vec4 o_color;
457 
458         void main (void)
459         {
460             o_color = vec4(v_coords.xyz, 1.0);
461             return;
462         })";
463     compile(shaderString, SH_VARIABLES);
464 }
465 
TEST_F(MSLOutputTest,FragColor)466 TEST_F(MSLOutputTest, FragColor)
467 {
468     const std::string &shaderString = R"(
469         void main ()
470         {
471             gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
472         })";
473     compile(shaderString, SH_VARIABLES);
474 }
475 
TEST_F(MSLOutputTest,MatrixIn)476 TEST_F(MSLOutputTest, MatrixIn)
477 {
478     const std::string &shaderString =
479         R"(#version 300 es
480         precision highp float;
481 
482         in mat4 mat;
483         out float out0;
484 
485         void main()
486         {
487             out0 = mat[0][0];
488         }
489         )";
490     compile(shaderString, SH_VARIABLES);
491 }
492 
TEST_F(MSLOutputTest,WhileTrue)493 TEST_F(MSLOutputTest, WhileTrue)
494 {
495     const std::string &shaderString =
496         R"(#version 300 es
497         precision mediump float;
498 
499         uniform float uf;
500         out vec4 my_FragColor;
501 
502         void main()
503         {
504             my_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
505             while (true)
506             {
507                 break;
508             }
509         })";
510     compile(shaderString, SH_VARIABLES);
511 }
512 
TEST_F(MSLOutputTest,ForTrue)513 TEST_F(MSLOutputTest, ForTrue)
514 {
515     const std::string &shaderString =
516         R"(#version 300 es
517         precision mediump float;
518 
519         uniform float uf;
520         out vec4 my_FragColor;
521 
522         void main()
523         {
524             my_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
525             for (;true;)
526             {
527                 break;
528             }
529         })";
530     compile(shaderString, SH_VARIABLES);
531 }
532 
TEST_F(MSLOutputTest,ForEmpty)533 TEST_F(MSLOutputTest, ForEmpty)
534 {
535     const std::string &shaderString =
536         R"(#version 300 es
537         precision mediump float;
538 
539         uniform float uf;
540         out vec4 my_FragColor;
541 
542         void main()
543         {
544             my_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
545             for (;;)
546             {
547                 break;
548             }
549         })";
550     compile(shaderString, SH_VARIABLES);
551 }
552 
TEST_F(MSLOutputTest,ForComplex)553 TEST_F(MSLOutputTest, ForComplex)
554 {
555     const std::string &shaderString =
556         R"(#version 300 es
557         precision mediump float;
558 
559         uniform float uf;
560         out vec4 my_FragColor;
561 
562         void main()
563         {
564             my_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
565             for (int i = 0, j = 2; i < j; ++i) {
566                 if (i == 0) continue;
567                 if (i == 42) break;
568                 my_FragColor.x += float(i);
569             }
570         })";
571     compile(shaderString, SH_VARIABLES);
572 }
573 
TEST_F(MSLOutputTest,ForSymbol)574 TEST_F(MSLOutputTest, ForSymbol)
575 {
576     const std::string &shaderString =
577         R"(#version 300 es
578         precision mediump float;
579 
580         uniform float uf;
581         out vec4 my_FragColor;
582 
583         void main()
584         {
585             bool cond = true;
586             for (;cond;)
587             {
588                 my_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
589                 cond = false;
590             }
591         })";
592     compile(shaderString, SH_VARIABLES);
593 }
594 
TEST_F(MSLOutputTest,DoWhileSymbol)595 TEST_F(MSLOutputTest, DoWhileSymbol)
596 {
597     const std::string &shaderString =
598         R"(#version 300 es
599         precision mediump float;
600 
601         uniform float uf;
602         out vec4 my_FragColor;
603 
604         void main()
605         {
606             bool cond = false;
607             do
608             {
609                 my_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
610             } while (cond);
611         })";
612     compile(shaderString, SH_VARIABLES);
613 }
614 
TEST_F(MSLOutputTest,AnonymousStruct)615 TEST_F(MSLOutputTest, AnonymousStruct)
616 {
617     const std::string &shaderString =
618         R"(
619         precision mediump float;
620         struct { vec4 v; } anonStruct;
621         void main() {
622             anonStruct.v = vec4(0.0,1.0,0.0,1.0);
623             gl_FragColor = anonStruct.v;
624         })";
625     compile(shaderString, SH_VARIABLES);
626     // TODO(anglebug.com/6395): This success condition is expected to fail now.
627     // When WebKit build is able to run the tests, this should be changed to something else.
628     //    ASSERT_TRUE(foundInCode(SH_MSL_METAL_OUTPUT, "__unnamed"));
629 }
630