1 //
2 // Copyright 2017 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // InitializeUninitializedVariables_test.cpp: Tests InitializeUninitializedVariables pass.
7 //
8
9 #include "common/angleutils.h"
10
11 #include "tests/test_utils/compiler_test.h"
12
13 namespace sh
14 {
15
16 namespace
17 {
18
19 class InitializeUninitializedVariables : public MatchOutputCodeTest
20 {
21 public:
InitializeUninitializedVariables()22 InitializeUninitializedVariables() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_ESSL_OUTPUT)
23 {
24 ShCompileOptions options{};
25 options.intermediateTree = true;
26 options.initializeUninitializedLocals = true;
27 options.validateAST = true;
28 setDefaultCompileOptions(options);
29 }
30 };
31
32 // Tests that when unnamed variables must be initialized, the variables get internal names.
TEST_F(InitializeUninitializedVariables,VariableNamesInPrototypesUnnamedOut)33 TEST_F(InitializeUninitializedVariables, VariableNamesInPrototypesUnnamedOut)
34 {
35 const char kShader[] = R"(#version 300 es
36 precision highp float;
37 out vec4 o;
38 void f(out float, out float);
39 void main()
40 {
41 o = vec4(0.5);
42 f(o.r, o.g);
43 }
44 void f(out float r, out float)
45 {
46 r = 1.0;
47 }
48 )";
49 const char kExpected[] = R"(#version 300 es
50 out highp vec4 _uo;
51 void _uf(out highp float _ur, out highp float sbc2);
52 void main(){
53 (_uo = vec4(0.5, 0.5, 0.5, 0.5));
54 _uf(_uo.x, _uo.y);
55 }
56 void _uf(out highp float _ur, out highp float sbc2){
57 (_ur = 0.0);
58 (sbc2 = 0.0);
59 (_ur = 1.0);
60 }
61 )";
62 compile(kShader);
63 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
64 }
65
66 // Tests that when unnamed variables must be initialized, the variables get internal names.
TEST_F(InitializeUninitializedVariables,VariableNamesInPrototypesUnnamedOut2)67 TEST_F(InitializeUninitializedVariables, VariableNamesInPrototypesUnnamedOut2)
68 {
69 const char kShader[] = R"(#version 300 es
70 precision highp float;
71 out vec4 o;
72 void f(out float, out float);
73 void g(out float a, out float b)
74 {
75 f(a, b);
76 }
77 void main()
78 {
79 o = vec4(0.5);
80 g(o.r, o.g);
81 }
82 void f(out float r, out float)
83 {
84 r = 1.0;
85 }
86 )";
87 const char kExpected[] = R"(#version 300 es
88 out highp vec4 _uo;
89 void _uf(out highp float _ur, out highp float sbc5);
90 void _ug(out highp float _ua, out highp float _ub){
91 (_ua = 0.0);
92 (_ub = 0.0);
93 _uf(_ua, _ub);
94 }
95 void main(){
96 (_uo = vec4(0.5, 0.5, 0.5, 0.5));
97 _ug(_uo.x, _uo.y);
98 }
99 void _uf(out highp float _ur, out highp float sbc5){
100 (_ur = 0.0);
101 (sbc5 = 0.0);
102 (_ur = 1.0);
103 }
104 )";
105 compile(kShader);
106 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
107 }
108
109 // Tests that when unnamed variables must be initialized, the variables get internal names.
110 // Tests the case where local z is initialized with a function f, when f must be rewritten.
TEST_F(InitializeUninitializedVariables,VariableNamesInPrototypesUnnamedOut3)111 TEST_F(InitializeUninitializedVariables, VariableNamesInPrototypesUnnamedOut3)
112 {
113 const char kShader[] = R"(#version 300 es
114 precision highp float;
115 out vec4 o;
116 float f(out float r, out float)
117 {
118 r = 1.0;
119 return 3.0;
120 }
121 void main()
122 {
123 o = vec4(0.5);
124 float z = f(o.r, o.g);
125 }
126 )";
127 const char kExpected[] = R"(#version 300 es
128 out highp vec4 _uo;
129 highp float _uf(out highp float _ur, out highp float sbc0){
130 (_ur = 0.0);
131 (sbc0 = 0.0);
132 (_ur = 1.0);
133 return 3.0;
134 }
135 void main(){
136 (_uo = vec4(0.5, 0.5, 0.5, 0.5));
137 highp float _uz = _uf(_uo.x, _uo.y);
138 }
139 )";
140 compile(kShader);
141 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
142 }
143
144 } // namespace
145
146 } // namespace sh
147