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