Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / glsl3 / tricky-loop-conditions.html
blob1bf57d1a02171418e2677e464550f43b859c8ea7
1 <!--
2 Copyright (c) 2019 The Khronos Group Inc.
3 Use of this source code is governed by an MIT-style license that can be
4 found in the LICENSE.txt file.
5 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <title>GLSL tricky loop conditions and loop expressions</title>
12 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
13 <script src="../../js/js-test-pre.js"></script>
14 <script src="../../js/webgl-test-utils.js"></script>
15 <script src="../../js/glsl-conformance-test.js"></script>
16 </head>
17 <body>
18 <div id="description"></div>
19 <div id="console"></div>
20 <!--
21 Some tricky shader expressions might be subject to syntax tree transformations that need to create
22 new statements. Ensure that these expressions also work inside loop conditions and loop expressions.
23 -->
24 <script type="application/javascript">
25 "use strict";
26 description("Indexing complex array expressions");
27 debug("");
29 // All the templates run the given sequence:
30 // 1. loopExpression or loopCondition
31 // 2. loopContents
32 // 3. Break loop if it's done loopIterations iterations, else go back to 1.
34 var forLoopExpressionTemplate = [
35 '#version 300 es',
36 'precision mediump float;',
37 'out vec4 color;',
38 '$(globalScopePrefix)',
39 'void main() {',
40 '$(mainPrefix)',
41 ' for (int i = 0; true; $(loopExpression))',
42 ' {',
43 ' ++i;',
44 ' if (i > 1) {',
45 ' $(loopContents)',
46 ' if (i > $(loopIterations)) { break; }',
47 ' }',
48 ' }',
49 ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
50 '}'
51 ].join('\n');
53 var forLoopConditionTemplate = [
54 '#version 300 es',
55 'precision mediump float;',
56 'out vec4 color;',
57 '$(globalScopePrefix)',
58 'void main() {',
59 '$(mainPrefix)',
60 ' for (int i = 1; $(loopCondition); ++i)',
61 ' {',
62 ' $(loopContents)',
63 ' if (i >= $(loopIterations)) { break; }',
64 ' }',
65 ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
66 '}'
67 ].join('\n');
69 var whileLoopConditionTemplate = [
70 '#version 300 es',
71 'precision mediump float;',
72 'out vec4 color;',
73 '$(globalScopePrefix)',
74 'void main() {',
75 '$(mainPrefix)',
76 ' int i = 0;',
77 ' while ($(loopCondition))',
78 ' {',
79 ' $(loopContents)',
80 ' ++i;',
81 ' if (i >= $(loopIterations)) { break; }',
82 ' }',
83 ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
84 '}'
85 ].join('\n');
87 var doWhileLoopConditionTemplate = [
88 '#version 300 es',
89 'precision mediump float;',
90 'out vec4 color;',
91 '$(globalScopePrefix)',
92 'void main() {',
93 '$(mainPrefix)',
94 ' int i = 0;',
95 // Run the loop condition one extra time to make the different test types behave the same
96 ' $(loopCondition);',
97 ' do {',
98 ' $(loopContents)',
99 ' ++i;',
100 ' if (i >= $(loopIterations)) { break; }',
101 ' }',
102 ' while ($(loopCondition));',
103 ' color = ($(passCondition)) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);',
105 ].join('\n');
107 var testDataList = [
109 description: 'indexing an array assignment',
110 globalScopePrefix: '',
111 mainPrefix: [
112 'float a[2] = float[2](0.0, 0.0);',
113 'float b[2] = float[2](2.0, 1.0);',
114 'float c = 0.0;'
115 ].join('\n'),
116 loopExpression: 'c = (a = b)[0]',
117 loopCondition: 'bool((c = (a = b)[0]) + 1.0)',
118 loopContents: 'b[0] += 1.0;',
119 loopIterations: 3,
120 passCondition: 'abs(c - 4.0) < 0.01'
123 description: 'indexing a function returning an array',
124 globalScopePrefix: [
125 'int sideEffectCounter = 0;',
126 'float[2] functionReturnArray() {',
127 ' ++sideEffectCounter;',
128 ' return float[2](float(sideEffectCounter), 1.0);',
130 ].join('\n'),
131 mainPrefix: 'float c = 0.0;',
132 loopExpression: 'c = functionReturnArray()[0]',
133 loopCondition: 'bool(c = functionReturnArray()[0])',
134 loopContents: '',
135 loopIterations: 3,
136 passCondition: 'abs(c - 3.0) < 0.01 && sideEffectCounter == 3'
139 description: 'indexing an array constructor',
140 globalScopePrefix: '',
141 mainPrefix: 'int c = 0;',
142 loopExpression: 'c = (int[2](c + 1, c + 2))[1]',
143 loopCondition: 'bool(c = (int[2](c + 1, c + 2))[1])',
144 loopContents: '',
145 loopIterations: 3,
146 passCondition: 'c == 6'
149 description: 'indexing an array constructor inside a sequence operator',
150 globalScopePrefix: [
151 'int sideEffectCounter = 0;',
152 'int func() {',
153 ' sideEffectCounter++;',
154 ' return sideEffectCounter;',
156 ].join('\n'),
157 mainPrefix: 'int c = 0;',
158 loopExpression: 'c = (func(), (int[2](c + 1, c + 2))[1])',
159 loopCondition: 'bool(c = (func(), (int[2](c + 1, c + 2))[1]))',
160 loopContents: '',
161 loopIterations: 3,
162 passCondition: 'c == 6 && sideEffectCounter == 3'
165 description: 'dynamic indexing of a vector',
166 globalScopePrefix: '',
167 mainPrefix: [
168 'vec4 v = vec4(1.0, 2.0, 3.0, 4.0);',
169 'float c = 0.0;',
170 'int j = 0;'
171 ].join('\n'),
172 loopExpression: 'c = v[j]',
173 loopCondition: 'bool(c = v[j])',
174 loopContents: '++j;',
175 loopIterations: 3,
176 passCondition: 'abs(c - 3.0) < 0.01'
179 description: 'short-circuiting operator',
180 globalScopePrefix: [
181 'int sideEffectCounter = 0;',
182 'bool func() {',
183 ' sideEffectCounter++;',
184 ' return sideEffectCounter > 0;',
186 ].join('\n'),
187 mainPrefix: '',
188 loopExpression: 'func() && func()',
189 loopCondition: 'func() && func()',
190 loopContents: '',
191 loopIterations: 3,
192 passCondition: 'sideEffectCounter == 6'
195 description: 'short-circuiting operator',
196 globalScopePrefix: [
197 'int sideEffectCounter = 0;',
198 'bool func() {',
199 ' sideEffectCounter++;',
200 ' return sideEffectCounter > 0;',
202 ].join('\n'),
203 mainPrefix: '',
204 loopExpression: 'func() || func()',
205 loopCondition: 'func() || func()',
206 loopContents: '',
207 loopIterations: 3,
208 passCondition: 'sideEffectCounter == 3'
211 description: 'short-circuiting operator',
212 globalScopePrefix: [
213 'int sideEffectCounterA = 0;',
214 'bool funcA() {',
215 ' sideEffectCounterA++;',
216 ' return sideEffectCounterA > 1;',
217 '}',
218 'int sideEffectCounterB = 0;',
219 'bool funcB() {',
220 ' sideEffectCounterB++;',
221 ' return sideEffectCounterB > 0;',
223 ].join('\n'),
224 mainPrefix: '',
225 loopExpression: 'funcA() ? true : funcB()',
226 loopCondition: 'funcA() ? true : funcB()',
227 loopContents: '',
228 loopIterations: 3,
229 passCondition: 'sideEffectCounterA == 3 && sideEffectCounterB == 1'
232 description: 'high-precision constant',
233 globalScopePrefix: [
234 'const highp float f = 2048.5;',
235 'uniform mediump float u_zero;'
236 ].join('\n'),
237 mainPrefix: 'float c = 0.0;',
238 loopExpression: 'c = fract(u_zero + f)',
239 loopCondition: 'bool(c = fract(u_zero + f))',
240 loopContents: '',
241 loopIterations: 3,
242 passCondition: 'abs(c - 0.5) < 0.01'
245 description: 'l-value indexing side effects combined with static indexing of a vector',
246 globalScopePrefix: [
247 'int sideEffectCounter = 0;',
248 'int func() {',
249 ' sideEffectCounter++;',
250 ' return sideEffectCounter > 1 ? 1 : 0;',
252 ].join('\n'),
253 mainPrefix: [
254 'vec4[2] V;',
255 'V[0] = vec4(1.0);',
256 'V[1] = vec4(3.0);'
257 ].join('\n'),
258 loopExpression: 'V[func()][0]++',
259 loopCondition: 'bool(V[func()][0]++)',
260 loopContents: '',
261 loopIterations: 3,
262 passCondition: 'abs(V[0][0] - 2.0) < 0.01 && abs(V[1][0] - 5.0) < 0.01 && sideEffectCounter == 3'
265 description: 'l-value indexing side effects combined with dynamically indexing a vector',
266 globalScopePrefix: [
267 'int sideEffectCounter = 0;',
268 'uniform int u_zero;',
269 'int func() {',
270 ' sideEffectCounter++;',
271 ' return sideEffectCounter > 1 ? 1 : 0;',
273 ].join('\n'),
274 mainPrefix: [
275 'vec4[2] V;',
276 'V[0] = vec4(1.0);',
277 'V[1] = vec4(3.0);'
278 ].join('\n'),
279 loopExpression: 'V[func()][u_zero + 1]++',
280 loopCondition: 'bool(V[func()][u_zero + 1]++)',
281 loopContents: '',
282 loopIterations: 3,
283 passCondition: 'abs(V[0][1] - 2.0) < 0.01 && abs(V[1][1] - 5.0) < 0.01 && sideEffectCounter == 3'
287 var tests = [];
289 var wtu = WebGLTestUtils;
291 for (var i = 0; i < testDataList.length; ++i) {
292 var testData = testDataList[i];
293 if ('loopCondition' in testData) {
294 tests.push({
295 fShaderSource: wtu.replaceParams(forLoopConditionTemplate, testData),
296 fShaderSuccess: true,
297 linkSuccess: true,
298 passMsg: 'Test ' + testData.description + ': ' + testData.loopCondition + ' inside a for loop condition'
300 tests.push({
301 fShaderSource: wtu.replaceParams(whileLoopConditionTemplate, testData),
302 fShaderSuccess: true,
303 linkSuccess: true,
304 passMsg: 'Test ' + testData.description + ': ' + testData.loopCondition + ' inside a while loop condition'
306 tests.push({
307 fShaderSource: wtu.replaceParams(doWhileLoopConditionTemplate, testData),
308 fShaderSuccess: true,
309 linkSuccess: true,
310 passMsg: 'Test ' + testData.description + ': ' + testData.loopCondition + ' inside a do-while loop condition'
313 if ('loopExpression' in testData) {
314 tests.push({
315 fShaderSource: wtu.replaceParams(forLoopExpressionTemplate, testData),
316 fShaderSuccess: true,
317 linkSuccess: true,
318 passMsg: 'Test ' + testData.description + ': ' + testData.loopExpression + ' inside a for loop expression'
323 GLSLConformanceTester.runRenderTests(tests, 2);
325 </script>
326 </body>
327 </html>