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