1# encoding=utf-8
2# Copyright © 2019 Google
3
4# Permission is hereby granted, free of charge, to any person obtaining a copy
5# of this software and associated documentation files (the "Software"), to deal
6# in the Software without restriction, including without limitation the rights
7# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8# copies of the Software, and to permit persons to whom the Software is
9# furnished to do so, subject to the following conditions:
10
11# The above copyright notice and this permission notice shall be included in
12# all copies or substantial portions of the Software.
13
14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20# SOFTWARE.
21
22from __future__ import print_function
23import sys
24import subprocess
25import tempfile
26import re
27from collections import namedtuple
28
29
30Test = namedtuple("Test", "name source match_re")
31
32
33TESTS = [
34    Test("f32 simple division",
35         """
36         uniform mediump float a, b;
37
38         void main()
39         {
40                 gl_FragColor.rgba = vec4(a / b);
41         }
42         """,
43         r'\(expression +float16_t +/'),
44    Test("i32 simple division",
45         """
46         #version 300 es
47         precision mediump float;
48         precision mediump int;
49         uniform mediump int a, b;
50
51         out vec4 color;
52
53         void main()
54         {
55                 color = vec4(a / b);
56         }
57         """,
58         r'\(expression +int16_t +/'),
59    Test("u32 simple division",
60         """
61         #version 300 es
62         precision mediump float;
63         precision mediump int;
64         uniform mediump uint a, b;
65
66         out vec4 color;
67
68         void main()
69         {
70                 color = vec4(a / b);
71         }
72         """,
73         r'\(expression +uint16_t +/'),
74    Test("dot",
75         """
76         uniform mediump vec2 a, b;
77
78         void main()
79         {
80                 gl_FragColor.rgba = vec4(dot(a, b));
81         }
82         """,
83         r'\(expression +float16_t +dot\b'),
84    Test("f32 array with const index",
85         """
86         precision mediump float;
87
88         uniform float in_simple[2];
89
90         void main()
91         {
92                 gl_FragColor = vec4(in_simple[0] / in_simple[1]);
93         }
94         """,
95         r'\(expression +float16_t +/'),
96    Test("i32 array with const index",
97         """
98         #version 300 es
99         precision mediump float;
100         precision mediump int;
101
102         uniform int in_simple[2];
103
104         out vec4 color;
105
106         void main()
107         {
108                 color = vec4(in_simple[0] / in_simple[1]);
109         }
110         """,
111         r'\(expression +int16_t +/'),
112    Test("u32 array with const index",
113         """
114         #version 300 es
115         precision mediump float;
116         precision mediump int;
117
118         uniform uint in_simple[2];
119
120         out vec4 color;
121
122         void main()
123         {
124                 color = vec4(in_simple[0] / in_simple[1]);
125         }
126         """,
127         r'\(expression +uint16_t +/'),
128    Test("f32 array with uniform index",
129         """
130         precision mediump float;
131
132         uniform float in_simple[2];
133         uniform int i0, i1;
134
135         void main()
136         {
137                 gl_FragColor = vec4(in_simple[i0] / in_simple[i1]);
138         }
139         """,
140         r'\(expression +float16_t +/'),
141    Test("i32 array with uniform index",
142         """
143         #version 300 es
144         precision mediump float;
145         precision mediump int;
146
147         uniform int in_simple[2];
148         uniform int i0, i1;
149
150         out vec4 color;
151
152         void main()
153         {
154                 color = vec4(in_simple[i0] / in_simple[i1]);
155         }
156         """,
157         r'\(expression +int16_t +/'),
158    Test("u32 array with uniform index",
159         """
160         #version 300 es
161         precision mediump float;
162         precision mediump int;
163
164         uniform uint in_simple[2];
165         uniform int i0, i1;
166
167         out vec4 color;
168
169         void main()
170         {
171                 color = vec4(in_simple[i0] / in_simple[i1]);
172         }
173         """,
174         r'\(expression +uint16_t +/'),
175    Test("f32 array-of-array with const index",
176         """
177         #version 310 es
178         precision mediump float;
179
180         uniform float in_aoa[2][2];
181
182         layout(location = 0) out float out_color;
183
184         void main()
185         {
186                 out_color = in_aoa[0][0] / in_aoa[1][1];
187         }
188         """,
189         r'\(expression +float16_t +/'),
190    Test("i32 array-of-array with const index",
191         """
192         #version 310 es
193         precision mediump float;
194         precision mediump int;
195
196         uniform int in_aoa[2][2];
197
198         layout(location = 0) out highp int out_color;
199
200         void main()
201         {
202                 out_color = in_aoa[0][0] / in_aoa[1][1];
203         }
204         """,
205         r'\(expression +int16_t +/'),
206    Test("u32 array-of-array with const index",
207         """
208         #version 310 es
209         precision mediump float;
210         precision mediump int;
211
212         uniform uint in_aoa[2][2];
213
214         layout(location = 0) out highp uint out_color;
215
216         void main()
217         {
218                 out_color = in_aoa[0][0] / in_aoa[1][1];
219         }
220         """,
221         r'\(expression +uint16_t +/'),
222    Test("f32 array-of-array with uniform index",
223         """
224         #version 310 es
225         precision mediump float;
226
227         uniform float in_aoa[2][2];
228         uniform int i0, i1;
229
230         layout(location = 0) out float out_color;
231
232         void main()
233         {
234                 out_color = in_aoa[i0][i0] / in_aoa[i1][i1];
235         }
236         """,
237         r'\(expression +float16_t +/'),
238    Test("i32 array-of-array with uniform index",
239         """
240         #version 310 es
241         precision mediump float;
242         precision mediump int;
243
244         uniform int in_aoa[2][2];
245         uniform int i0, i1;
246
247         layout(location = 0) out highp int out_color;
248
249         void main()
250         {
251                 out_color = in_aoa[i0][i0] / in_aoa[i1][i1];
252         }
253         """,
254         r'\(expression +int16_t +/'),
255    Test("u32 array-of-array with uniform index",
256         """
257         #version 310 es
258         precision mediump float;
259         precision mediump int;
260
261         uniform uint in_aoa[2][2];
262         uniform int i0, i1;
263
264         layout(location = 0) out highp uint out_color;
265
266         void main()
267         {
268                 out_color = in_aoa[i0][i0] / in_aoa[i1][i1];
269         }
270         """,
271         r'\(expression +uint16_t +/'),
272    Test("f32 array index",
273         """
274         uniform mediump float a, b;
275         uniform mediump float values[2];
276
277         void main()
278         {
279                 gl_FragColor.rgba = vec4(values[int(a / b)]);
280         }
281         """,
282         r'\(expression +float16_t +/'),
283    Test("i32 array index",
284         """
285         #version 310 es
286         precision mediump float;
287         precision mediump int;
288
289         uniform mediump int a, b;
290         uniform mediump int values[2];
291
292         out highp int color;
293
294         void main()
295         {
296                 color = values[a / b];
297         }
298         """,
299         r'\(expression +int16_t +/'),
300    Test("f32 function",
301         """
302         precision mediump float;
303
304         uniform float a, b;
305
306         mediump float
307         get_a()
308         {
309                 return a;
310         }
311
312         float
313         get_b()
314         {
315                 return b;
316         }
317
318         void main()
319         {
320                 gl_FragColor = vec4(get_a() / get_b());
321         }
322         """,
323         r'\(expression +float16_t +/'),
324    Test("i32 function",
325         """
326         #version 310 es
327         precision mediump float;
328         precision mediump int;
329
330         uniform int a, b;
331
332         mediump int
333         get_a()
334         {
335                 return a;
336         }
337
338         int
339         get_b()
340         {
341                 return b;
342         }
343
344         out highp int color;
345
346         void main()
347         {
348                 color = get_a() / get_b();
349         }
350         """,
351         r'\(expression +int16_t +/'),
352    Test("u32 function",
353         """
354         #version 310 es
355         precision mediump float;
356         precision mediump int;
357
358         uniform uint a, b;
359
360         mediump uint
361         get_a()
362         {
363                 return a;
364         }
365
366         uint
367         get_b()
368         {
369                 return b;
370         }
371
372         out highp uint color;
373
374         void main()
375         {
376                 color = get_a() / get_b();
377         }
378         """,
379         r'\(expression +uint16_t +/'),
380    Test("f32 function mediump args",
381         """
382         precision mediump float;
383
384         uniform float a, b;
385
386         mediump float
387         do_div(float x, float y)
388         {
389                 return x / y;
390         }
391
392         void main()
393         {
394                 gl_FragColor = vec4(do_div(a, b));
395         }
396         """,
397         r'\(expression +float16_t +/'),
398    Test("i32 function mediump args",
399         """
400         #version 310 es
401         precision mediump float;
402         precision mediump int;
403
404         uniform int a, b;
405
406         mediump int
407         do_div(int x, int y)
408         {
409                 return x / y;
410         }
411
412         out highp int color;
413
414         void main()
415         {
416                 color = do_div(a, b);
417         }
418         """,
419         r'\(expression +int16_t +/'),
420    Test("u32 function mediump args",
421         """
422         #version 310 es
423         precision mediump float;
424         precision mediump int;
425
426         uniform uint a, b;
427
428         mediump uint
429         do_div(uint x, uint y)
430         {
431                 return x / y;
432         }
433
434         out highp uint color;
435
436         void main()
437         {
438                 color = do_div(a, b);
439         }
440         """,
441         r'\(expression +uint16_t +/'),
442    Test("f32 function highp args",
443         """
444         precision mediump float;
445
446         uniform float a, b;
447
448         mediump float
449         do_div(highp float x, highp float y)
450         {
451                 return x / y;
452         }
453
454         void main()
455         {
456                 gl_FragColor = vec4(do_div(a, b));
457         }
458         """,
459         r'\(expression +float +/'),
460    Test("i32 function highp args",
461         """
462         #version 310 es
463         precision mediump float;
464         precision mediump int;
465
466         uniform int a, b;
467
468         mediump int
469         do_div(highp int x, highp int y)
470         {
471                 return x / y;
472         }
473
474         out highp int color;
475
476         void main()
477         {
478                  color = do_div(a, b);
479         }
480         """,
481         r'\(expression +int +/'),
482    Test("u32 function highp args",
483         """
484         #version 310 es
485         precision mediump float;
486         precision mediump int;
487
488         uniform uint a, b;
489
490         mediump uint
491         do_div(highp uint x, highp uint y)
492         {
493                 return x / y;
494         }
495
496         out highp uint color;
497
498         void main()
499         {
500                  color = do_div(a, b);
501         }
502         """,
503         r'\(expression +uint +/'),
504    Test("f32 function inout different precision highp",
505         """
506         uniform mediump float a, b;
507
508         void
509         do_div(inout highp float x, highp float y)
510         {
511                 x = x / y;
512         }
513
514         void main()
515         {
516                 mediump float temp = a;
517                 do_div(temp, b);
518                 gl_FragColor = vec4(temp);
519         }
520         """,
521         r'\(expression +float +/'),
522    Test("i32 function inout different precision highp",
523         """
524         #version 310 es
525         uniform mediump int a, b;
526
527         void
528         do_div(inout highp int x, highp int y)
529         {
530                 x = x / y;
531         }
532
533         out mediump int color;
534
535         void main()
536         {
537                 mediump int temp = a;
538                 do_div(temp, b);
539                 color = temp;
540         }
541         """,
542         r'\(expression +int +/'),
543    Test("u32 function inout different precision highp",
544         """
545         #version 310 es
546         uniform mediump uint a, b;
547
548         void
549         do_div(inout highp uint x, highp uint y)
550         {
551                 x = x / y;
552         }
553
554         out mediump uint color;
555
556         void main()
557         {
558                 mediump uint temp = a;
559                 do_div(temp, b);
560                 color = temp;
561         }
562         """,
563         r'\(expression +uint +/'),
564    Test("f32 function inout different precision mediump",
565         """
566         uniform highp float a, b;
567
568         void
569         do_div(inout mediump float x, mediump float y)
570         {
571                 x = x / y;
572         }
573
574         void main()
575         {
576                 highp float temp = a;
577                 do_div(temp, b);
578                 gl_FragColor = vec4(temp);
579         }
580         """,
581         r'\(expression +float16_t +/'),
582    Test("i32 function inout different precision mediump",
583         """
584         #version 310 es
585         uniform highp int a, b;
586
587         out highp int color;
588
589         void
590         do_div(inout mediump int x, mediump int y)
591         {
592                 x = x / y;
593         }
594
595         void main()
596         {
597                 highp int temp = a;
598                 do_div(temp, b);
599                 color = temp;
600         }
601         """,
602         r'\(expression +int16_t +/'),
603    Test("u32 function inout different precision mediump",
604         """
605         #version 310 es
606         uniform highp uint a, b;
607
608         out highp uint color;
609
610         void
611         do_div(inout mediump uint x, mediump uint y)
612         {
613                 x = x / y;
614         }
615
616         void main()
617         {
618                 highp uint temp = a;
619                 do_div(temp, b);
620                 color = temp;
621         }
622         """,
623         r'\(expression +uint16_t +/'),
624    Test("f32 if",
625         """
626         precision mediump float;
627
628         uniform float a, b;
629
630         void
631         main()
632         {
633                 if (a / b < 0.31)
634                         gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
635                 else
636                         gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
637         }
638         """,
639         r'\(expression +float16_t +/'),
640    Test("i32 if",
641         """
642         #version 310 es
643         precision mediump float;
644         precision mediump int;
645
646         uniform int a, b;
647
648         out vec4 color;
649
650         void
651         main()
652         {
653                 if (a / b < 10)
654                         color = vec4(0.0, 1.0, 0.0, 1.0);
655                 else
656                         color = vec4(1.0, 0.0, 0.0, 1.0);
657         }
658         """,
659         r'\(expression +int16_t +/'),
660    Test("u32 if",
661         """
662         #version 310 es
663         precision mediump float;
664         precision mediump int;
665
666         uniform uint a, b;
667
668         out vec4 color;
669
670         void
671         main()
672         {
673                 if (a / b < 10u)
674                         color = vec4(0.0, 1.0, 0.0, 1.0);
675                 else
676                         color = vec4(1.0, 0.0, 0.0, 1.0);
677         }
678         """,
679         r'\(expression +uint16_t +/'),
680    Test("matrix",
681         """
682         precision mediump float;
683
684         uniform vec2 a;
685         uniform mat2 b;
686
687         void main()
688         {
689             gl_FragColor = vec4(b * a, 0.0, 0.0);
690         }
691         """,
692         r'\(expression +f16vec2 \*.*\bf16mat2\b'),
693    Test("f32 simple struct deref",
694         """
695         precision mediump float;
696
697         struct simple {
698                 float a, b;
699         };
700
701         uniform simple in_simple;
702
703         void main()
704         {
705                 gl_FragColor = vec4(in_simple.a / in_simple.b);
706         }
707         """,
708         r'\(expression +float16_t +/'),
709    Test("i32 simple struct deref",
710         """
711         #version 310 es
712         precision mediump float;
713         precision mediump int;
714
715         struct simple {
716                 int a, b;
717         };
718
719         uniform simple in_simple;
720
721         out highp int color;
722
723         void main()
724         {
725                 color = in_simple.a / in_simple.b;
726         }
727         """,
728         r'\(expression +int16_t +/'),
729    Test("u32 simple struct deref",
730         """
731         #version 310 es
732         precision mediump float;
733         precision mediump int;
734
735         struct simple {
736                 uint a, b;
737         };
738
739         uniform simple in_simple;
740
741         out highp uint color;
742
743         void main()
744         {
745                 color = in_simple.a / in_simple.b;
746         }
747         """,
748         r'\(expression +uint16_t +/'),
749    Test("f32 embedded struct deref",
750         """
751         precision mediump float;
752
753         struct simple {
754                 float a, b;
755         };
756
757         struct embedded {
758                 simple a, b;
759         };
760
761         uniform embedded in_embedded;
762
763         void main()
764         {
765                 gl_FragColor = vec4(in_embedded.a.a / in_embedded.b.b);
766         }
767         """,
768         r'\(expression +float16_t +/'),
769    Test("i32 embedded struct deref",
770         """
771         #version 310 es
772         precision mediump float;
773         precision mediump int;
774
775         struct simple {
776                 int a, b;
777         };
778
779         struct embedded {
780                 simple a, b;
781         };
782
783         uniform embedded in_embedded;
784
785         out highp int color;
786
787         void main()
788         {
789                 color = in_embedded.a.a / in_embedded.b.b;
790         }
791         """,
792         r'\(expression +int16_t +/'),
793    Test("u32 embedded struct deref",
794         """
795         #version 310 es
796         precision mediump float;
797         precision mediump int;
798
799         struct simple {
800                 uint a, b;
801         };
802
803         struct embedded {
804                 simple a, b;
805         };
806
807         uniform embedded in_embedded;
808
809         out highp uint color;
810
811         void main()
812         {
813                 color = in_embedded.a.a / in_embedded.b.b;
814         }
815         """,
816         r'\(expression +uint16_t +/'),
817    Test("f32 arrayed struct deref",
818         """
819         precision mediump float;
820
821         struct simple {
822                 float a, b;
823         };
824
825         struct arrayed {
826                 simple a[2];
827         };
828
829         uniform arrayed in_arrayed;
830
831         void main()
832         {
833                 gl_FragColor = vec4(in_arrayed.a[0].a / in_arrayed.a[1].b);
834         }
835         """,
836         r'\(expression +float16_t +/'),
837    Test("i32 arrayed struct deref",
838         """
839         #version 310 es
840         precision mediump float;
841         precision mediump int;
842
843         struct simple {
844                 int a, b;
845         };
846
847         struct arrayed {
848                 simple a[2];
849         };
850
851         uniform arrayed in_arrayed;
852
853         out highp int color;
854
855         void main()
856         {
857                 color = in_arrayed.a[0].a / in_arrayed.a[1].b;
858         }
859         """,
860         r'\(expression +int16_t +/'),
861    Test("u32 arrayed struct deref",
862         """
863         #version 310 es
864         precision mediump float;
865         precision mediump int;
866
867         struct simple {
868                 uint a, b;
869         };
870
871         struct arrayed {
872                 simple a[2];
873         };
874
875         uniform arrayed in_arrayed;
876
877         out highp uint color;
878
879         void main()
880         {
881                 color = in_arrayed.a[0].a / in_arrayed.a[1].b;
882         }
883         """,
884         r'\(expression +uint16_t +/'),
885    Test("f32 mixed precision not lowered",
886         """
887         uniform mediump float a;
888         uniform highp float b;
889
890         void main()
891         {
892                 gl_FragColor = vec4(a / b);
893         }
894         """,
895         r'\(expression +float +/'),
896    Test("i32 mixed precision not lowered",
897         """
898         #version 310 es
899         uniform mediump int a;
900         uniform highp int b;
901
902         out mediump int color;
903
904         void main()
905         {
906                 color = a / b;
907         }
908         """,
909         r'\(expression +int +/'),
910    Test("u32 mixed precision not lowered",
911         """
912         #version 310 es
913         uniform mediump uint a;
914         uniform highp uint b;
915
916         out mediump uint color;
917
918         void main()
919         {
920                 color = a / b;
921         }
922         """,
923         r'\(expression +uint +/'),
924    Test("f32 sampler array",
925         """
926         #version 320 es
927         precision mediump float;
928         precision mediump int;
929
930         uniform sampler2D tex[2];
931         // highp shouldn't affect the return value of texture2D
932         uniform highp vec2 coord;
933         uniform float divisor;
934         uniform int index;
935
936         out highp vec4 color;
937
938         void main()
939         {
940                 color = texture2D(tex[index], coord) / divisor;
941         }
942         """,
943         r'\(expression +f16vec4 +/.*\(tex +f16vec4 +'),
944    Test("f32 texture sample",
945         """
946         precision mediump float;
947
948         uniform sampler2D tex;
949         // highp shouldn't affect the return value of texture2D
950         uniform highp vec2 coord;
951         uniform float divisor;
952
953         void main()
954         {
955                 gl_FragColor = texture2D(tex, coord) / divisor;
956         }
957         """,
958         r'\(expression +f16vec4 +/.*\(tex +f16vec4 +'),
959    Test("i32 texture sample",
960         """
961         #version 310 es
962         precision mediump float;
963         precision mediump int;
964
965         uniform mediump isampler2D tex;
966         // highp shouldn't affect the return value of texture
967         uniform highp vec2 coord;
968         uniform int divisor;
969
970         out highp ivec4 color;
971
972         void main()
973         {
974                 color = texture(tex, coord) / divisor;
975         }
976         """,
977         r'\(expression +i16vec4 +/.*\(tex +i16vec4 +'),
978    Test("u32 texture sample",
979         """
980         #version 310 es
981         precision mediump float;
982         precision mediump int;
983
984         uniform mediump usampler2D tex;
985         // highp shouldn't affect the return value of texture
986         uniform highp vec2 coord;
987         uniform uint divisor;
988
989         out highp uvec4 color;
990
991         void main()
992         {
993                 color = texture(tex, coord) / divisor;
994         }
995         """,
996         r'\(expression +u16vec4 +/.*\(tex +u16vec4 +'),
997    Test("f32 image array",
998         """
999         #version 320 es
1000         precision mediump float;
1001
1002         layout(rgba16f) readonly uniform mediump image2D img[2];
1003         // highp shouldn't affect the return value of imageLoad
1004         uniform highp ivec2 coord;
1005         uniform float divisor;
1006
1007         out highp vec4 color;
1008
1009         void main()
1010         {
1011                 color = imageLoad(img[1], coord) / divisor;
1012         }
1013         """,
1014         r'\(expression +f16vec4 +/'),
1015    Test("f32 image load",
1016         """
1017         #version 310 es
1018         precision mediump float;
1019         precision mediump int;
1020
1021         layout(rgba16f) readonly uniform mediump image2D img;
1022         // highp shouldn't affect the return value of imageLoad
1023         uniform highp ivec2 coord;
1024         uniform float divisor;
1025
1026         out highp vec4 color;
1027
1028         void main()
1029         {
1030                 color = imageLoad(img, coord) / divisor;
1031         }
1032         """,
1033         r'\(expression +f16vec4 +/'),
1034    Test("i32 image load",
1035         """
1036         #version 310 es
1037         precision mediump float;
1038         precision mediump int;
1039
1040         layout(rgba16i) readonly uniform mediump iimage2D img;
1041         // highp shouldn't affect the return value of imageLoad
1042         uniform highp ivec2 coord;
1043         uniform int divisor;
1044
1045         out highp ivec4 color;
1046
1047         void main()
1048         {
1049                 color = imageLoad(img, coord) / divisor;
1050         }
1051         """,
1052         r'\(expression +i16vec4 +/'),
1053    Test("u32 image load",
1054         """
1055         #version 310 es
1056         precision mediump float;
1057         precision mediump int;
1058
1059         layout(rgba16ui) readonly uniform mediump uimage2D img;
1060         // highp shouldn't affect the return value of imageLoad
1061         uniform highp ivec2 coord;
1062         uniform uint divisor;
1063
1064         out highp uvec4 color;
1065
1066         void main()
1067         {
1068                 color = imageLoad(img, coord) / divisor;
1069         }
1070         """,
1071         r'\(expression +u16vec4 +/'),
1072    Test("f32 expression in lvalue",
1073         """
1074         uniform mediump float a, b;
1075
1076         void main()
1077         {
1078                 gl_FragColor = vec4(1.0);
1079                 gl_FragColor[int(a / b)] = 0.5;
1080         }
1081         """,
1082         r'\(expression +float16_t +/'),
1083    Test("i32 expression in lvalue",
1084         """
1085         #version 310 es
1086         precision mediump float;
1087         precision mediump int;
1088
1089         uniform mediump int a, b;
1090
1091         out vec4 color;
1092
1093         void main()
1094         {
1095                 color = vec4(1.0);
1096                 color[a / b] = 0.5;
1097         }
1098         """,
1099         r'\(expression +int16_t +/'),
1100    Test("f32 builtin with const arg",
1101         """
1102         uniform mediump float a;
1103
1104         void main()
1105         {
1106                 gl_FragColor = vec4(min(a, 3.0));
1107         }
1108         """,
1109         r'\(expression +float16_t min'),
1110    Test("i32 builtin with const arg",
1111         """
1112         #version 310 es
1113         uniform mediump int a;
1114
1115         out highp int color;
1116
1117         void main()
1118         {
1119                 color = min(a, 3);
1120         }
1121         """,
1122         r'\(expression +int16_t min'),
1123    Test("u32 builtin with const arg",
1124         """
1125         #version 310 es
1126         uniform mediump uint a;
1127
1128         out highp uint color;
1129
1130         void main()
1131         {
1132                 color = min(a, 3u);
1133         }
1134         """,
1135         r'\(expression +uint16_t min'),
1136    Test("dFdx",
1137         """
1138         #version 300 es
1139         precision mediump float;
1140
1141         in vec4 var;
1142         out vec4 color;
1143
1144         void main()
1145         {
1146                 color = dFdx(var);
1147         }
1148         """,
1149         r'\(expression +f16vec4 +dFdx +\(expression +f16vec4'),
1150    Test("dFdy",
1151         """
1152         #version 300 es
1153         precision mediump float;
1154
1155         in vec4 var;
1156         out vec4 color;
1157
1158         void main()
1159         {
1160                 color = dFdy(var);
1161         }
1162         """,
1163         r'\(expression +f16vec4 +dFdy +\(expression +f16vec4'),
1164    Test("textureSize",
1165         """
1166         #version 310 es
1167         precision mediump float;
1168         precision mediump int;
1169
1170         uniform mediump sampler2D tex;
1171         out ivec2 color;
1172
1173         void main()
1174         {
1175                 color = textureSize(tex, 0) * ivec2(2);
1176         }
1177         """,
1178         r'expression ivec2 \* \(txs ivec2 \(var_ref tex'),
1179    Test("floatBitsToInt",
1180         """
1181         #version 310 es
1182         precision mediump float;
1183         precision mediump int;
1184
1185         uniform float val;
1186         out int color;
1187
1188         void main()
1189         {
1190                 color = floatBitsToInt(val + 1.0) + 1;
1191         }
1192         """,
1193         r'expression int bitcast_f2i \(expression float'),
1194    Test("floatBitsToUint",
1195         """
1196         #version 310 es
1197         precision mediump float;
1198         precision mediump int;
1199
1200         uniform float val;
1201         out uint color;
1202
1203         void main()
1204         {
1205                 color = floatBitsToUint(val + 1.0) + 1u;
1206         }
1207         """,
1208         r'expression uint bitcast_f2u \(expression float'),
1209    Test("intBitsToFloat",
1210         """
1211         #version 310 es
1212         precision mediump float;
1213         precision mediump int;
1214
1215         uniform int val;
1216         out float color;
1217
1218         void main()
1219         {
1220                 color = intBitsToFloat(val + 1) + 1.0;
1221         }
1222         """,
1223         r'expression float bitcast_i2f \(expression int'),
1224    Test("uintBitsToFloat",
1225         """
1226         #version 310 es
1227         precision mediump float;
1228         precision mediump int;
1229
1230         uniform uint val;
1231         out float color;
1232
1233         void main()
1234         {
1235                 color = uintBitsToFloat(val + 1u) + 1.0;
1236         }
1237         """,
1238         r'expression float bitcast_u2f \(expression uint'),
1239    Test("bitfieldReverse",
1240         """
1241         #version 310 es
1242         precision mediump float;
1243         precision mediump int;
1244
1245         uniform int val;
1246         out int color;
1247
1248         void main()
1249         {
1250                 color = bitfieldReverse(val + 1) + 1;
1251         }
1252         """,
1253         r'expression int bitfield_reverse \(expression int'),
1254    Test("frexp",
1255         """
1256         #version 310 es
1257         precision mediump float;
1258         precision mediump int;
1259
1260         uniform float val;
1261         out float color;
1262         out int color2;
1263
1264         void main()
1265         {
1266                 int y;
1267                 float x = frexp(val + 1.0, y);
1268                 color = x + 1.0;
1269                 color2 = y + 1;
1270         }
1271         """,
1272         r'assign  \(x\) \(var_ref x\)  \(expression float f162f'),
1273    Test("ldexp",
1274         """
1275         #version 310 es
1276         precision mediump float;
1277         precision mediump int;
1278
1279         uniform float val;
1280         uniform int exp;
1281         out float color;
1282
1283         void main()
1284         {
1285                 color = ldexp(val + 1.0, exp + 1) + 1.0;
1286         }
1287         """,
1288         r'expression float ldexp \(expression float'),
1289    Test("uaddCarry",
1290         """
1291         #version 310 es
1292         precision mediump float;
1293         precision mediump int;
1294
1295         uniform uint x, y;
1296         out uint color;
1297
1298         void main()
1299         {
1300                 lowp uint carry;
1301                 color = uaddCarry(x * 2u, y * 2u, carry) * 2u;
1302                 color *= carry;
1303         }
1304         """,
1305         r'expression uint \+ \(var_ref x\) \(var_ref y'),
1306    Test("usubBorrow",
1307         """
1308         #version 310 es
1309         precision mediump float;
1310         precision mediump int;
1311
1312         uniform uint x, y;
1313         out uint color;
1314
1315         void main()
1316         {
1317                 lowp uint borrow;
1318                 color = usubBorrow(x * 2u, y * 2u, borrow) * 2u;
1319                 color *= borrow;
1320         }
1321         """,
1322         r'expression uint \+ \(var_ref x\) \(expression uint neg'),
1323    Test("imulExtended",
1324         """
1325         #version 310 es
1326         precision mediump float;
1327         precision mediump int;
1328
1329         uniform int x, y;
1330         out int color;
1331
1332         void main()
1333         {
1334                 int msb, lsb;
1335                 imulExtended(x + 2, y + 2, msb, lsb);
1336                 color = msb + lsb;
1337         }
1338         """,
1339         r'expression int64_t \* \(expression int'),
1340    Test("umulExtended",
1341         """
1342         #version 310 es
1343         precision mediump float;
1344         precision mediump int;
1345
1346         uniform uint x, y;
1347         out uint color;
1348
1349         void main()
1350         {
1351                 uint msb, lsb;
1352                 umulExtended(x + 2u, y + 2u, msb, lsb);
1353                 color = msb + lsb;
1354         }
1355         """,
1356         r'expression uint64_t \* \(expression uint'),
1357    Test("unpackUnorm2x16",
1358         """
1359         #version 310 es
1360         precision mediump float;
1361         precision mediump int;
1362
1363         uniform uint val;
1364         out vec2 color;
1365
1366         void main()
1367         {
1368                 color = unpackUnorm2x16(val + 1u) + vec2(1.0);
1369         }
1370         """,
1371         r'expression vec2 unpackUnorm2x16 \(expression uint'),
1372    Test("unpackSnorm2x16",
1373         """
1374         #version 310 es
1375         precision mediump float;
1376         precision mediump int;
1377
1378         uniform uint val;
1379         out vec2 color;
1380
1381         void main()
1382         {
1383                 color = unpackSnorm2x16(val + 1u) + vec2(1.0);
1384         }
1385         """,
1386         r'expression vec2 unpackSnorm2x16 \(expression uint'),
1387    Test("packUnorm2x16",
1388         """
1389         #version 310 es
1390         precision mediump float;
1391         precision mediump int;
1392
1393         uniform vec2 val;
1394         out uint color;
1395
1396         void main()
1397         {
1398                 color = packUnorm2x16(val + vec2(1.0)) + 1u;
1399         }
1400         """,
1401         r'expression uint packUnorm2x16 \(expression vec2'),
1402    Test("packSnorm2x16",
1403         """
1404         #version 310 es
1405         precision mediump float;
1406         precision mediump int;
1407
1408         uniform vec2 val;
1409         out uint color;
1410
1411         void main()
1412         {
1413                 color = packSnorm2x16(val + vec2(1.0)) + 1u;
1414         }
1415         """,
1416         r'expression uint packSnorm2x16 \(expression vec2'),
1417    Test("packHalf2x16",
1418         """
1419         #version 310 es
1420         precision mediump float;
1421         precision mediump int;
1422
1423         uniform vec2 val;
1424         out uint color;
1425
1426         void main()
1427         {
1428                 color = packHalf2x16(val + vec2(1.0)) + 1u;
1429         }
1430         """,
1431         r'expression uint packHalf2x16 \(expression vec2'),
1432    Test("packUnorm4x8",
1433         """
1434         #version 310 es
1435         precision mediump float;
1436         precision mediump int;
1437
1438         uniform vec4 val;
1439         out uint color;
1440
1441         void main()
1442         {
1443                 color = packUnorm4x8(val + vec4(1.0)) + 1u;
1444         }
1445         """,
1446         r'expression uint packUnorm4x8 \(expression vec4'),
1447    Test("packSnorm4x8",
1448         """
1449         #version 310 es
1450         precision mediump float;
1451         precision mediump int;
1452
1453         uniform vec4 val;
1454         out uint color;
1455
1456         void main()
1457         {
1458                 color = packSnorm4x8(val + vec4(1.0)) + 1u;
1459         }
1460         """,
1461         r'expression uint packSnorm4x8 \(expression vec4'),
1462    Test("interpolateAtCentroid",
1463         """
1464         #version 320 es
1465         precision mediump float;
1466         precision mediump int;
1467
1468         in float val;
1469         out float color;
1470
1471         void main()
1472         {
1473                 color = interpolateAtCentroid(val) + 1.0;
1474         }
1475         """,
1476         r'expression float16_t interpolate_at_centroid \(expression float16_t'),
1477    Test("interpolateAtOffset",
1478         """
1479         #version 320 es
1480         precision mediump float;
1481         precision mediump int;
1482
1483         uniform highp vec2 offset;
1484         in float val;
1485         out float color;
1486
1487         void main()
1488         {
1489                 color = interpolateAtOffset(val, offset) + 1.0;
1490         }
1491         """,
1492         r'expression float16_t interpolate_at_offset \(expression float16_t'),
1493    Test("interpolateAtSample",
1494         """
1495         #version 320 es
1496         precision mediump float;
1497         precision mediump int;
1498
1499         uniform highp int sample_index;
1500         in float val;
1501         out float color;
1502
1503         void main()
1504         {
1505                 color = interpolateAtSample(val, sample_index) + 1.0;
1506         }
1507         """,
1508         r'expression float16_t interpolate_at_sample \(expression float16_t'),
1509    Test("bitfieldExtract",
1510         """
1511         #version 310 es
1512         precision mediump float;
1513         precision mediump int;
1514
1515         uniform highp int offset, bits;
1516         uniform int val;
1517         out int color;
1518
1519         void main()
1520         {
1521                 color = bitfieldExtract(val, offset, bits) + 1;
1522         }
1523         """,
1524         r'expression int16_t bitfield_extract \(expression int16_t'),
1525    Test("bitfieldInsert",
1526         """
1527         #version 310 es
1528         precision mediump float;
1529         precision mediump int;
1530
1531         uniform highp int offset, bits;
1532         uniform int val, val2;
1533         out int color;
1534
1535         void main()
1536         {
1537                 color = bitfieldInsert(val, val2, offset, bits) + 1;
1538         }
1539         """,
1540         r'expression int16_t bitfield_insert \(expression int16_t'),
1541    Test("bitCount",
1542         """
1543         #version 310 es
1544         precision mediump float;
1545         precision mediump int;
1546
1547         uniform highp int val;
1548         out int color;
1549
1550         void main()
1551         {
1552                 color = bitCount(val) + 1;
1553         }
1554         """,
1555         r'expression int16_t \+ \(expression int16_t i2imp \(expression int bit_count \(var_ref val'),
1556    Test("findLSB",
1557         """
1558         #version 310 es
1559         precision mediump float;
1560         precision mediump int;
1561
1562         uniform highp int val;
1563         out int color;
1564
1565         void main()
1566         {
1567                 color = findLSB(val) + 1;
1568         }
1569         """,
1570         r'expression int16_t \+ \(expression int16_t i2imp \(expression int find_lsb \(var_ref val'),
1571    Test("findMSB",
1572         """
1573         #version 310 es
1574         precision mediump float;
1575         precision mediump int;
1576
1577         uniform highp int val;
1578         out int color;
1579
1580         void main()
1581         {
1582                 color = findMSB(val) + 1;
1583         }
1584         """,
1585         r'expression int16_t \+ \(expression int16_t i2imp \(expression int find_msb \(var_ref val'),
1586    Test("unpackHalf2x16",
1587         """
1588         #version 310 es
1589         precision mediump float;
1590         precision mediump int;
1591
1592         uniform highp uint val;
1593         out vec2 color;
1594
1595         void main()
1596         {
1597                 color = unpackHalf2x16(val) + vec2(1.0);
1598         }
1599         """,
1600         r'expression f16vec2 \+ \(expression f16vec2 f2fmp \(expression vec2 unpackHalf2x16 \(var_ref val'),
1601    Test("unpackUnorm4x8",
1602         """
1603         #version 310 es
1604         precision mediump float;
1605         precision mediump int;
1606
1607         uniform highp uint val;
1608         out vec4 color;
1609
1610         void main()
1611         {
1612                 color = unpackUnorm4x8(val) + vec4(1.0);
1613         }
1614         """,
1615         r'expression f16vec4 \+ \(expression f16vec4 f2fmp \(expression vec4 unpackUnorm4x8 \(var_ref val'),
1616    Test("unpackSnorm4x8",
1617         """
1618         #version 310 es
1619         precision mediump float;
1620         precision mediump int;
1621
1622         uniform highp uint val;
1623         out vec4 color;
1624
1625         void main()
1626         {
1627                 color = unpackSnorm4x8(val) + vec4(1.0);
1628         }
1629         """,
1630         r'expression f16vec4 \+ \(expression f16vec4 f2fmp \(expression vec4 unpackSnorm4x8 \(var_ref val'),
1631    Test("f32 csel",
1632         """
1633         #version 300 es
1634         precision mediump float;
1635
1636         in vec4 var;
1637         out vec4 color;
1638
1639         void main()
1640         {
1641                 color = (var.x > var.y) ? var : vec4(10.0);
1642         }
1643         """,
1644         r'\(constant +f16vec4 \(10'),
1645    Test("i32 csel",
1646         """
1647         #version 310 es
1648         precision mediump int;
1649
1650         in flat ivec4 var;
1651         out ivec4 color;
1652
1653         void main()
1654         {
1655                 color = (var.x > var.y) ? var : ivec4(10);
1656         }
1657         """,
1658         r'\(constant +i16vec4 \(10'),
1659    Test("u32 csel",
1660         """
1661         #version 310 es
1662         precision mediump int;
1663
1664         in flat uvec4 var;
1665         out uvec4 color;
1666
1667         void main()
1668         {
1669                 color = (var.x > var.y) ? var : uvec4(10);
1670         }
1671         """,
1672         r'\(constant +u16vec4 \(10'),
1673    Test("f32 loop counter",
1674         """
1675         #version 300 es
1676         precision mediump float;
1677
1678         uniform float n, incr;
1679         out float color;
1680
1681         void main()
1682         {
1683                 color = 0.0;
1684                 for (float x = 0.0; x < n; x += incr)
1685                    color += x;
1686         }
1687         """,
1688         r'\(assign  \(x\) \(var_ref x\)  \(expression float16_t \+ \(var_ref x\) \(expression float16_t f2fmp \(var_ref incr'),
1689    Test("i32 loop counter",
1690         """
1691         #version 310 es
1692         precision mediump float;
1693         precision mediump int;
1694
1695         uniform int n, incr;
1696         out int color;
1697
1698         void main()
1699         {
1700                 color = 0;
1701                 for (int x = 0; x < n; x += incr)
1702                    color += x;
1703         }
1704         """,
1705         r'\(assign  \(x\) \(var_ref x\)  \(expression int16_t \+ \(var_ref x\) \(expression int16_t i2imp \(var_ref incr'),
1706    Test("u32 loop counter",
1707         """
1708         #version 310 es
1709         precision mediump float;
1710         precision mediump int;
1711
1712         uniform uint n, incr;
1713         out uint color;
1714
1715         void main()
1716         {
1717                 color = 0u;
1718                 for (uint x = 0u; x < n; x += incr)
1719                    color += x;
1720         }
1721         """,
1722         r'\(assign  \(x\) \(var_ref x\)  \(expression uint16_t \+ \(var_ref x\) \(expression uint16_t u2ump \(var_ref incr'),
1723    Test("f32 temp array",
1724         """
1725         #version 300 es
1726         precision mediump float;
1727
1728         uniform float x,y;
1729         out float color;
1730
1731         void main()
1732         {
1733                 float a[2] = float[2](x, y);
1734                 if (x > 0.0)
1735                     a[1] = 3.0;
1736                 color = a[0] + a[1];
1737         }
1738         """,
1739         r'\(constant float16_t \(3'),
1740    Test("i32 temp array",
1741         """
1742         #version 310 es
1743         precision mediump int;
1744
1745         uniform int x,y;
1746         out int color;
1747
1748         void main()
1749         {
1750                 int a[2] = int[2](x, y);
1751                 if (x > 0)
1752                     a[1] = 3;
1753                 color = a[0] + a[1];
1754         }
1755         """,
1756         r'\(constant int16_t \(3'),
1757    Test("u32 temp array",
1758         """
1759         #version 310 es
1760         precision mediump int;
1761
1762         uniform uint x,y;
1763         out uint color;
1764
1765         void main()
1766         {
1767                 uint a[2] = uint[2](x, y);
1768                 if (x > 0u)
1769                     a[1] = 3u;
1770                 color = a[0] + a[1];
1771         }
1772         """,
1773         r'\(constant uint16_t \(3'),
1774    Test("f32 temp array of array",
1775         """
1776         #version 310 es
1777         precision mediump float;
1778
1779         uniform float x,y;
1780         out float color;
1781
1782         void main()
1783         {
1784                 float a[2][2] = float[2][2](float[2](x, y), float[2](x, y));
1785                 if (x > 0.0)
1786                     a[1][1] = 3.0;
1787                 color = a[0][0] + a[1][1];
1788         }
1789         """,
1790         r'\(constant float16_t \(3'),
1791    Test("i32 temp array of array",
1792         """
1793         #version 310 es
1794         precision mediump int;
1795
1796         uniform int x,y;
1797         out int color;
1798
1799         void main()
1800         {
1801                 int a[2][2] = int[2][2](int[2](x, y), int[2](x, y));
1802                 if (x > 0)
1803                     a[1][1] = 3;
1804                 color = a[0][0] + a[1][1];
1805         }
1806         """,
1807         r'\(constant int16_t \(3'),
1808    Test("u32 temp array of array",
1809         """
1810         #version 310 es
1811         precision mediump int;
1812
1813         uniform uint x,y;
1814         out uint color;
1815
1816         void main()
1817         {
1818                 uint a[2][2] = uint[2][2](uint[2](x, y), uint[2](x, y));
1819                 if (x > 0u)
1820                     a[1][1] = 3u;
1821                 color = a[0][0] + a[1][1];
1822         }
1823         """,
1824         r'\(constant uint16_t \(3'),
1825    Test("f32 temp array of array assigned from highp",
1826         """
1827         #version 310 es
1828         precision mediump float;
1829
1830         uniform float x,y;
1831         out float color;
1832
1833         void main()
1834         {
1835                 highp float b[2][2] = float[2][2](float[2](x, y), float[2](x, y));
1836                 float a[2][2];
1837                 a = b;
1838                 if (x > 0.0)
1839                     a[1][1] = 3.0;
1840                 color = a[0][0] + a[1][1];
1841         }
1842         """,
1843         r'\(constant float16_t \(3'),
1844    Test("i32 temp array of array assigned from highp",
1845         """
1846         #version 310 es
1847         precision mediump int;
1848
1849         uniform int x,y;
1850         out int color;
1851
1852         void main()
1853         {
1854                 highp int b[2][2] = int[2][2](int[2](x, y), int[2](x, y));
1855                 int a[2][2];
1856                 a = b;
1857                 if (x > 0)
1858                     a[1][1] = 3;
1859                 color = a[0][0] + a[1][1];
1860         }
1861         """,
1862         r'\(constant int16_t \(3'),
1863    Test("u32 temp array of array assigned from highp",
1864         """
1865         #version 310 es
1866         precision mediump int;
1867
1868         uniform uint x,y;
1869         out uint color;
1870
1871         void main()
1872         {
1873                 highp uint b[2][2] = uint[2][2](uint[2](x, y), uint[2](x, y));
1874                 uint a[2][2];
1875                 a = b;
1876                 if (x > 0u)
1877                     a[1][1] = 3u;
1878                 color = a[0][0] + a[1][1];
1879         }
1880         """,
1881         r'\(constant uint16_t \(3'),
1882    Test("f32 temp array of array assigned to highp",
1883         """
1884         #version 310 es
1885         precision mediump float;
1886
1887         uniform float x,y;
1888         out float color;
1889
1890         void main()
1891         {
1892                 float a[2][2] = float[2][2](float[2](x, y), float[2](x, y));
1893                 highp float b[2][2];
1894                 b = a;
1895                 a = b;
1896                 if (x > 0.0)
1897                     a[1][1] = 3.0;
1898                 color = a[0][0] + a[1][1];
1899         }
1900         """,
1901         r'\(constant float16_t \(3'),
1902    Test("i32 temp array of array assigned to highp",
1903         """
1904         #version 310 es
1905         precision mediump int;
1906
1907         uniform int x,y;
1908         out int color;
1909
1910         void main()
1911         {
1912                 int a[2][2] = int[2][2](int[2](x, y), int[2](x, y));
1913                 highp int b[2][2];
1914                 b = a;
1915                 a = b;
1916                 if (x > 0)
1917                     a[1][1] = 3;
1918                 color = a[0][0] + a[1][1];
1919         }
1920         """,
1921         r'\(constant int16_t \(3'),
1922    Test("u32 temp array of array assigned to highp",
1923         """
1924         #version 310 es
1925         precision mediump int;
1926
1927         uniform uint x,y;
1928         out uint color;
1929
1930         void main()
1931         {
1932                 uint a[2][2] = uint[2][2](uint[2](x, y), uint[2](x, y));
1933                 highp uint b[2][2];
1934                 b = a;
1935                 a = b;
1936                 if (x > 0u)
1937                     a[1][1] = 3u;
1938                 color = a[0][0] + a[1][1];
1939         }
1940         """,
1941         r'\(constant uint16_t \(3'),
1942    Test("f32 temp array of array returned by function",
1943         """
1944         #version 310 es
1945         precision mediump float;
1946
1947         uniform float x,y;
1948         out float color;
1949
1950         float[2][2] f(void)
1951         {
1952            return float[2][2](float[2](x, y), float[2](x, y));
1953         }
1954
1955         void main()
1956         {
1957                 float a[2][2] = f();
1958                 if (x > 0.0)
1959                     a[1][1] = 3.0;
1960                 color = a[0][0] + a[1][1];
1961         }
1962         """,
1963         r'\(constant float16_t \(3'),
1964    Test("i32 temp array of array returned by function",
1965         """
1966         #version 310 es
1967         precision mediump int;
1968
1969         uniform int x,y;
1970         out int color;
1971
1972         int[2][2] f(void)
1973         {
1974            return int[2][2](int[2](x, y), int[2](x, y));
1975         }
1976
1977         void main()
1978         {
1979                 int a[2][2] = f();
1980                 if (x > 0)
1981                     a[1][1] = 3;
1982                 color = a[0][0] + a[1][1];
1983         }
1984         """,
1985         r'\(constant int16_t \(3'),
1986    Test("u32 temp array of array returned by function",
1987         """
1988         #version 310 es
1989         precision mediump int;
1990
1991         uniform uint x,y;
1992         out uint color;
1993
1994         uint[2][2] f(void)
1995         {
1996            return uint[2][2](uint[2](x, y), uint[2](x, y));
1997         }
1998
1999         void main()
2000         {
2001                 uint a[2][2] = f();
2002                 if (x > 0u)
2003                     a[1][1] = 3u;
2004                 color = a[0][0] + a[1][1];
2005         }
2006         """,
2007         r'\(constant uint16_t \(3'),
2008    Test("f32 temp array of array as function out",
2009         """
2010         #version 310 es
2011         precision mediump float;
2012
2013         uniform float x,y;
2014         out float color;
2015
2016         void f(out float[2][2] v)
2017         {
2018            v = float[2][2](float[2](x, y), float[2](x, y));
2019         }
2020
2021         void main()
2022         {
2023                 float a[2][2];
2024                 f(a);
2025                 if (x > 0.0)
2026                     a[1][1] = 3.0;
2027                 color = a[0][0] + a[1][1];
2028         }
2029         """,
2030         r'\(constant float16_t \(3'),
2031    Test("i32 temp array of array as function out",
2032         """
2033         #version 310 es
2034         precision mediump int;
2035
2036         uniform int x,y;
2037         out int color;
2038
2039         void f(out int[2][2] v)
2040         {
2041            v = int[2][2](int[2](x, y), int[2](x, y));
2042         }
2043
2044         void main()
2045         {
2046                 int a[2][2];
2047                 f(a);
2048                 if (x > 0)
2049                     a[1][1] = 3;
2050                 color = a[0][0] + a[1][1];
2051         }
2052         """,
2053         r'\(constant int16_t \(3'),
2054    Test("u32 temp array of array as function out",
2055         """
2056         #version 310 es
2057         precision mediump int;
2058
2059         uniform uint x,y;
2060         out uint color;
2061
2062         void f(out uint[2][2] v)
2063         {
2064            v = uint[2][2](uint[2](x, y), uint[2](x, y));
2065         }
2066
2067         void main()
2068         {
2069                 uint a[2][2];
2070                 f(a);
2071                 if (x > 0u)
2072                     a[1][1] = 3u;
2073                 color = a[0][0] + a[1][1];
2074         }
2075         """,
2076         r'\(constant uint16_t \(3'),
2077    Test("f32 temp array of array as function in",
2078         """
2079         #version 310 es
2080         precision mediump float;
2081
2082         uniform float x,y;
2083         out float color;
2084
2085         float[2][2] f(in float[2][2] v)
2086         {
2087            float t[2][2] = v;
2088            return t;
2089         }
2090
2091         void main()
2092         {
2093                 float a[2][2];
2094                 a = f(a);
2095                 if (x > 0.0)
2096                     a[1][1] = 3.0;
2097                 color = a[0][0] + a[1][1];
2098         }
2099         """,
2100         r'\(constant float16_t \(3'),
2101    Test("i32 temp array of array as function in",
2102         """
2103         #version 310 es
2104         precision mediump int;
2105
2106         uniform int x,y;
2107         out int color;
2108
2109         int[2][2] f(in int[2][2] v)
2110         {
2111            int t[2][2] = v;
2112            return t;
2113         }
2114
2115         void main()
2116         {
2117                 int a[2][2];
2118                 a = f(a);
2119                 if (x > 0)
2120                     a[1][1] = 3;
2121                 color = a[0][0] + a[1][1];
2122         }
2123         """,
2124         r'\(constant int16_t \(3'),
2125    Test("u32 temp array of array as function in",
2126         """
2127         #version 310 es
2128         precision mediump int;
2129
2130         uniform uint x,y;
2131         out uint color;
2132
2133         uint[2][2] f(in uint[2][2] v)
2134         {
2135            uint t[2][2] = v;
2136            return t;
2137         }
2138
2139         void main()
2140         {
2141                 uint a[2][2];
2142                 a = f(a);
2143                 if (x > 0u)
2144                     a[1][1] = 3u;
2145                 color = a[0][0] + a[1][1];
2146         }
2147         """,
2148         r'\(constant uint16_t \(3'),
2149    Test("f32 temp array of array as function inout",
2150         """
2151         #version 310 es
2152         precision mediump float;
2153
2154         uniform float x,y;
2155         out float color;
2156
2157         void f(inout float[2][2] v)
2158         {
2159            float t[2][2] = v;
2160            v = t;
2161         }
2162
2163         void main()
2164         {
2165                 float a[2][2];
2166                 f(a);
2167                 if (x > 0.0)
2168                     a[1][1] = 3.0;
2169                 color = a[0][0] + a[1][1];
2170         }
2171         """,
2172         r'\(constant float16_t \(3'),
2173    Test("i32 temp array of array as function inout",
2174         """
2175         #version 310 es
2176         precision mediump int;
2177
2178         uniform int x,y;
2179         out int color;
2180
2181         void f(inout int[2][2] v)
2182         {
2183            int t[2][2] = v;
2184            v = t;
2185         }
2186
2187         void main()
2188         {
2189                 int a[2][2];
2190                 f(a);
2191                 if (x > 0)
2192                     a[1][1] = 3;
2193                 color = a[0][0] + a[1][1];
2194         }
2195         """,
2196         r'\(constant int16_t \(3'),
2197    Test("u32 temp array of array as function inout",
2198         """
2199         #version 310 es
2200         precision mediump int;
2201
2202         uniform uint x,y;
2203         out uint color;
2204
2205         void f(inout uint[2][2] v)
2206         {
2207            uint t[2][2] = v;
2208            v = t;
2209         }
2210
2211         void main()
2212         {
2213                 uint a[2][2];
2214                 f(a);
2215                 if (x > 0u)
2216                     a[1][1] = 3u;
2217                 color = a[0][0] + a[1][1];
2218         }
2219         """,
2220         r'\(constant uint16_t \(3'),
2221    Test("f32 temp struct (not lowered in the presence of control flow - TODO)",
2222         """
2223         #version 300 es
2224         precision mediump float;
2225
2226         uniform float x,y;
2227         out float color;
2228
2229         void main()
2230         {
2231                 struct { float x,y; } s;
2232                 s.x = x;
2233                 s.y = y;
2234                 if (x > 0.0)
2235                     s.y = 3.0;
2236                 color = s.x + s.y;
2237         }
2238         """,
2239         r'\(constant float \(3'), # should be float16_t
2240    Test("i32 temp struct (not lowered in the presence of control flow - TODO)",
2241         """
2242         #version 300 es
2243         precision mediump int;
2244
2245         uniform int x,y;
2246         out int color;
2247
2248         void main()
2249         {
2250                 struct { int x,y; } s;
2251                 s.x = x;
2252                 s.y = y;
2253                 if (x > 0)
2254                     s.y = 3;
2255                 color = s.x + s.y;
2256         }
2257         """,
2258         r'\(constant int \(3'), # should be int16_t
2259    Test("u32 temp struct (not lowered in the presence of control flow - TODO)",
2260         """
2261         #version 300 es
2262         precision mediump int;
2263
2264         uniform uint x,y;
2265         out uint color;
2266
2267         void main()
2268         {
2269                 struct { uint x,y; } s;
2270                 s.x = x;
2271                 s.y = y;
2272                 if (x > 0u)
2273                     s.y = 3u;
2274                 color = s.x + s.y;
2275         }
2276         """,
2277         r'\(constant uint \(3'), # should be uint16_t
2278]
2279
2280
2281def compile_shader(standalone_compiler, source):
2282    with tempfile.NamedTemporaryFile(mode='wt', suffix='.frag') as source_file:
2283        print(source, file=source_file)
2284        source_file.flush()
2285        return subprocess.check_output([standalone_compiler,
2286                                        '--version', '300',
2287                                        '--lower-precision',
2288                                        '--dump-lir',
2289                                        source_file.name],
2290                                       universal_newlines=True)
2291
2292
2293def run_test(standalone_compiler, test):
2294    ir = compile_shader(standalone_compiler, test.source)
2295
2296    if re.search(test.match_re, ir) is None:
2297        print(ir)
2298        return False
2299
2300    return True
2301
2302
2303def main():
2304    standalone_compiler = sys.argv[1]
2305    passed = 0
2306
2307    for test in TESTS:
2308        print('Testing {} ... '.format(test.name), end='')
2309
2310        result = run_test(standalone_compiler, test)
2311
2312        if result:
2313            print('PASS')
2314            passed += 1
2315        else:
2316            print('FAIL')
2317
2318    print('{}/{} tests returned correct results'.format(passed, len(TESTS)))
2319    sys.exit(0 if passed == len(TESTS) else 1)
2320
2321
2322if __name__ == '__main__':
2323    main()
2324