loops-with-side-effects.html (4751B)
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 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>WebGL Loops and side-effects test</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 </head> 16 <body> 17 <div id="description"></div> 18 <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> 19 <div id="console"></div> 20 21 <!-- Variations on counter functions that used to give incorrect result on OSX 10.9 --> 22 <script id="counter0" type="x-shader/x-shader"> 23 bool s0 = false; 24 while(true) { 25 bool bar = s0; 26 if (!bar) { 27 bar = i < 3; 28 i = i + 1; 29 } 30 bool foo = !bar; 31 if (foo) { 32 break; 33 } 34 s0 = false; 35 n ++; 36 } 37 return n; 38 </script> 39 <script id="counter1" type="x-shader/x-shader"> 40 while(true) { 41 bool bar = i < 3; 42 i = i + 1; 43 bool foo = !bar; 44 if (foo) { 45 break; 46 } 47 n ++; 48 } 49 return n; 50 </script> 51 <script id="counter2" type="x-shader/x-shader"> 52 bool s0 = true; 53 while(true) { 54 bool bar = s0; 55 if (!bar) { 56 bar = i < 3; 57 i = i + 1; 58 } 59 bool foo = !bar; 60 if (foo) { 61 break; 62 } 63 s0 = false; 64 n ++; 65 } 66 return n; 67 </script> 68 <script id="counter3" type="x-shader/x-shader"> 69 bool s0 = true; 70 while(true) { 71 bool bar = s0; 72 if (!bar) { 73 bar = i++ < 3; 74 } 75 bool foo = !bar; 76 if (foo) { 77 break; 78 } 79 s0 = false; 80 n ++; 81 } 82 return n; 83 </script> 84 <script id="counter4" type="x-shader/x-shader"> 85 bool s0 = true; 86 while(true) { 87 bool bar = s0 || (i++ < 3); 88 bool foo = !bar; 89 if (foo) { 90 break; 91 } 92 s0 = false; 93 n ++; 94 } 95 return n; 96 </script> 97 <script id="counter5" type="x-shader/x-shader"> 98 bool s0 = true; 99 while(true) { 100 if (!(s0 || (i++ < 3))) { 101 break; 102 } 103 s0 = false; 104 n ++; 105 } 106 return n; 107 </script> 108 <script id="counter6" type="x-shader/x-shader"> 109 bool s0 = true; 110 while(s0 || (i++ < 3)) { 111 s0 = false; 112 n ++; 113 } 114 return n; 115 </script> 116 117 <script id="counter7" type="x-shader/x-shader"> 118 do { 119 n++; 120 } while (i++ < 3); 121 return n; 122 </script> 123 <script> 124 "use strict"; 125 description("This test checks for bugs related to loops and side-effects."); 126 127 debug(""); 128 129 var wtu = WebGLTestUtils; 130 var canvas = document.getElementById("canvas"); 131 var gl = wtu.create3DContext(canvas, null, 2); 132 133 if (!gl) { 134 testFailed("WebGL context does not exist"); 135 } else { 136 testPassed("WebGL context exists"); 137 138 for (var i = 0; i < 8; i++) { 139 tryCounter(document.getElementById("counter" + i).text); 140 debug(""); 141 } 142 } 143 144 function evaluateCounter(source) { 145 var jsSource = "(function(n, i) {" + 146 source.split("bool").join("var") + 147 "})(0, 0)"; 148 149 return eval(jsSource); 150 } 151 152 function makeFSSource(source) { 153 var fsSource = 154 "#version 300 es\n" + 155 "precision highp float;\n" + 156 "in float vertexCounter;\n" + 157 "uniform int uVertZero;\n" + 158 "uniform int uReference;\n" + 159 "out vec4 fragColor;\n" + 160 "int counter(int n, int i) {\n" + 161 source + 162 "}\n" + 163 "void main() {\n" + 164 " fragColor = vec4(0.0, 0.0, 0.0, 1.0);\n" + 165 " fragColor.r = float(counter(uVertZero, uVertZero) == uReference);\n" + 166 " fragColor.g = float(int(vertexCounter) == uReference);\n" + 167 "}\n"; 168 return fsSource; 169 } 170 171 function makeVSSource(source) { 172 var vsSource = 173 "#version 300 es\n" + 174 "out float vertexCounter;\n" + 175 "uniform int uFragZero;\n" + 176 "in vec4 vPosition;\n" + 177 "int counter(int n, int i) {\n" + 178 source + 179 "}\n" + 180 "void main() {\n" + 181 " gl_Position = vPosition;\n" + 182 " vertexCounter = float(counter(uFragZero, uFragZero));\n" + 183 "}\n"; 184 return vsSource; 185 } 186 187 function tryCounter(source) { 188 canvas.width = 50; canvas.height = 50; 189 gl.viewport(0, 0, canvas.width, canvas.height); 190 wtu.setupUnitQuad(gl, 0, 1); 191 192 var program = wtu.setupProgram(gl, [makeVSSource(source), makeFSSource(source)], ['vPosition'], [0], true); 193 194 gl.uniform1i(gl.getUniformLocation(program, "uVertZero"), 0); 195 gl.uniform1i(gl.getUniformLocation(program, "uFragZero"), 0); 196 197 var reference = evaluateCounter(source); 198 gl.uniform1i(gl.getUniformLocation(program, "uReference"), reference); 199 200 gl.useProgram(program); 201 wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 0]); 202 wtu.checkCanvas(gl, [255, 255, 0, 255]); 203 } 204 205 debug(""); 206 var successfullyParsed = true; 207 </script> 208 <script src="../../js/js-test-post.js"></script> 209 210 </body> 211 </html>