OLD | NEW |
(Empty) | |
| 1 GLSLConformanceTester = (function(){ |
| 2 |
| 3 var wtu = WebGLTestUtils; |
| 4 var defaultVertexShader = [ |
| 5 "attribute vec4 vPosition;", |
| 6 "void main()", |
| 7 "{", |
| 8 " gl_Position = vPosition;", |
| 9 "}" |
| 10 ].join('\n'); |
| 11 |
| 12 var defaultFragmentShader = [ |
| 13 "precision mediump float;", |
| 14 "void main()", |
| 15 "{", |
| 16 " gl_FragColor = vec4(1.0,0.0,0.0,1.0);", |
| 17 "}" |
| 18 ].join('\n'); |
| 19 |
| 20 function log(msg) { |
| 21 if (window.console && window.console.log) { |
| 22 window.console.log(msg); |
| 23 } |
| 24 } |
| 25 |
| 26 var vShaderDB = {}; |
| 27 var fShaderDB = {}; |
| 28 |
| 29 /** |
| 30 * vShaderSource: the source code for vertex shader |
| 31 * vShaderSuccess: true if vertex shader compiliation should |
| 32 * succeed. |
| 33 * fShaderSource: the source code for fragment shader |
| 34 * fShaderSuccess: true if fragment shader compiliation should |
| 35 * succeed. |
| 36 * linkSuccess: true of link should succeed |
| 37 * passMsg: msg to describe success condition. |
| 38 * |
| 39 */ |
| 40 function runOneTest(gl, info) { |
| 41 var passMsg = info.passMsg |
| 42 log(passMsg); |
| 43 |
| 44 if (info.vShaderSource === undefined) { |
| 45 if (info.vShaderId) { |
| 46 info.vShaderSource = document.getElementById(info.vShaderId).text; |
| 47 } else { |
| 48 info.vShader = 'defaultVertexShader'; |
| 49 info.vShaderSource = defaultVertexShader; |
| 50 } |
| 51 } |
| 52 if (info.fShaderSource === undefined) { |
| 53 if (info.fShaderId) { |
| 54 info.fShaderSource = document.getElementById(info.fShaderId).text; |
| 55 } else { |
| 56 info.fShader = 'defaultFragmentShader'; |
| 57 info.fShaderSource = defaultFragmentShader; |
| 58 } |
| 59 } |
| 60 |
| 61 var vSource = info.vShaderPrep ? info.vShaderPrep(info.vShaderSource) : |
| 62 info.vShaderSource; |
| 63 |
| 64 // Reuse identical shaders so we test shared shader. |
| 65 var vShader = vShaderDB[vSource]; |
| 66 if (!vShader) { |
| 67 vShader = wtu.loadShader(gl, vSource, gl.VERTEX_SHADER); |
| 68 if (info.vShaderTest) { |
| 69 if (!info.vShaderTest(vShader)) { |
| 70 testFailed("[vertex shader test] " + passMsg); |
| 71 return; |
| 72 } |
| 73 } |
| 74 // As per GLSL 1.0.17 10.27 we can only check for success on |
| 75 // compileShader, not failure. |
| 76 if (info.vShaderSuccess && !vShader) { |
| 77 testFailed("[unexpected vertex shader compile status] (expected: " + |
| 78 info.vShaderSuccess + ") " + passMsg); |
| 79 } |
| 80 // Save the shaders so we test shared shader. |
| 81 if (vShader) { |
| 82 vShaderDB[vSource] = vShader; |
| 83 } |
| 84 } |
| 85 |
| 86 var fSource = info.fShaderPrep ? info.fShaderPrep(info.fShaderSource) : |
| 87 info.fShaderSource; |
| 88 |
| 89 // Reuse identical shaders so we test shared shader. |
| 90 var fShader = fShaderDB[fSource]; |
| 91 if (!fShader) { |
| 92 fShader = wtu.loadShader(gl, fSource, gl.FRAGMENT_SHADER); |
| 93 if (info.fShaderTest) { |
| 94 if (!info.fShaderTest(fShader)) { |
| 95 testFailed("[fragment shdaer test] " + passMsg); |
| 96 return; |
| 97 } |
| 98 } |
| 99 //debug(fShader == null ? "fail" : "succeed"); |
| 100 // As per GLSL 1.0.17 10.27 we can only check for success on |
| 101 // compileShader, not failure. |
| 102 if (info.fShaderSuccess && !fShader) { |
| 103 testFailed("[unexpected fragment shader compile status] (expected: " + |
| 104 info.fShaderSuccess + ") " + passMsg); |
| 105 return; |
| 106 } |
| 107 // Safe the shaders so we test shared shader. |
| 108 if (fShader) { |
| 109 fShaderDB[fSource] = fShader; |
| 110 } |
| 111 } |
| 112 |
| 113 if (vShader && fShader) { |
| 114 var program = gl.createProgram(); |
| 115 gl.attachShader(program, vShader); |
| 116 gl.attachShader(program, fShader); |
| 117 gl.linkProgram(program); |
| 118 var linked = (gl.getProgramParameter(program, gl.LINK_STATUS) != 0); |
| 119 if (!linked) { |
| 120 var error = gl.getProgramInfoLog(program); |
| 121 log("*** Error linking program '"+program+"':"+error); |
| 122 } |
| 123 if (linked != info.linkSuccess) { |
| 124 testFailed("[unexpected link status] " + passMsg); |
| 125 return; |
| 126 } |
| 127 } else { |
| 128 if (info.linkSuccess) { |
| 129 testFailed("[link failed] " + passMsg); |
| 130 return; |
| 131 } |
| 132 } |
| 133 testPassed(passMsg); |
| 134 } |
| 135 |
| 136 function runTests(shaderInfos) { |
| 137 var wtu = WebGLTestUtils; |
| 138 var canvas = document.createElement('canvas'); |
| 139 var gl = wtu.create3DContext(); |
| 140 if (!gl) { |
| 141 testFailed("context does not exist"); |
| 142 finishTest(); |
| 143 return; |
| 144 } |
| 145 |
| 146 for (var ii = 0; ii < shaderInfos.length; ++ii) { |
| 147 runOneTest(gl, shaderInfos[ii]); |
| 148 } |
| 149 |
| 150 finishTest(); |
| 151 }; |
| 152 |
| 153 function loadExternalShaders(filename, passMsg) { |
| 154 var shaderInfos = []; |
| 155 var lines = wtu.readFileList(filename); |
| 156 for (var ii = 0; ii < lines.length; ++ii) { |
| 157 var info = { |
| 158 vShaderSource: defaultVertexShader, |
| 159 vShaderSuccess: true, |
| 160 fShaderSource: defaultFragmentShader, |
| 161 fShaderSuccess: true, |
| 162 linkSuccess: true, |
| 163 }; |
| 164 |
| 165 var line = lines[ii]; |
| 166 var files = line.split(/ +/); |
| 167 var passMsg = ""; |
| 168 for (var jj = 0; jj < files.length; ++jj) { |
| 169 var file = files[jj]; |
| 170 var shaderSource = wtu.readFile(file); |
| 171 var firstLine = shaderSource.split("\n")[0]; |
| 172 var success = undefined; |
| 173 if (firstLine.indexOf("fail") >= 0) { |
| 174 success = false; |
| 175 } else if (firstLine.indexOf("succeed") >= 0) { |
| 176 success = true; |
| 177 } |
| 178 if (success === undefined) { |
| 179 testFailed("bad first line in " + file + ":" + firstLine); |
| 180 continue; |
| 181 } |
| 182 if (!wtu.startsWith(firstLine, "// ")) { |
| 183 testFailed("bad first line in " + file + ":" + firstLine); |
| 184 continue; |
| 185 } |
| 186 passMsg = passMsg + (passMsg.length ? ", " : "") + firstLine.substr(3); |
| 187 if (wtu.endsWith(file, ".vert")) { |
| 188 info.vShaderSource = shaderSource; |
| 189 info.vShaderSuccess = success; |
| 190 } else if (wtu.endsWith(file, ".frag")) { |
| 191 info.fShaderSource = shaderSource; |
| 192 info.fShaderSuccess = success; |
| 193 } |
| 194 } |
| 195 info.linkSuccess = info.vShaderSuccess && info.fShaderSuccess; |
| 196 info.passMsg = passMsg; |
| 197 shaderInfos.push(info); |
| 198 } |
| 199 return shaderInfos; |
| 200 } |
| 201 |
| 202 function getSource(elem) { |
| 203 var str = elem.text; |
| 204 return str.replace(/^\s*/, '').replace(/\s*$/, ''); |
| 205 } |
| 206 |
| 207 function getPassMessage(source) { |
| 208 var lines = source.split('\n'); |
| 209 return lines[0].substring(3); |
| 210 } |
| 211 |
| 212 function getSuccess(msg) { |
| 213 if (msg.indexOf("fail") >= 0) { |
| 214 return false; |
| 215 } |
| 216 if (msg.indexOf("succeed") >= 0) { |
| 217 return true; |
| 218 } |
| 219 testFailed("bad test description. Must have 'fail' or 'success'"); |
| 220 } |
| 221 |
| 222 function runTest() { |
| 223 var vShaderElem = document.getElementById('vertexShader'); |
| 224 var vShaderSource = defaultVertexShader; |
| 225 var vShaderSuccess = true; |
| 226 |
| 227 var fShaderElem = document.getElementById('fragmentShader'); |
| 228 var fShaderSource = defaultFragmentShader; |
| 229 var fShaderSuccess = true; |
| 230 |
| 231 var passMsg = undefined; |
| 232 |
| 233 if (vShaderElem) { |
| 234 vShaderSource = getSource(vShaderElem); |
| 235 passMsg = getPassMessage(vShaderSource); |
| 236 vShaderSuccess = getSuccess(passMsg); |
| 237 } |
| 238 |
| 239 if (fShaderElem) { |
| 240 fShaderSource = getSource(fShaderElem); |
| 241 passMsg = getPassMessage(fShaderSource); |
| 242 fShaderSuccess = getSuccess(passMsg); |
| 243 } |
| 244 |
| 245 var linkSuccess = vShaderSuccess && fShaderSuccess; |
| 246 |
| 247 if (passMsg === undefined) { |
| 248 testFailed("no test shader found."); |
| 249 finishTest(); |
| 250 return; |
| 251 } |
| 252 |
| 253 var info = { |
| 254 vShaderSource: vShaderSource, |
| 255 vShaderSuccess: vShaderSuccess, |
| 256 fShaderSource: fShaderSource, |
| 257 fShaderSuccess: fShaderSuccess, |
| 258 linkSuccess: linkSuccess, |
| 259 passMsg: passMsg |
| 260 }; |
| 261 description(passMsg); |
| 262 runTests([info]); |
| 263 } |
| 264 |
| 265 return { |
| 266 runTest: runTest, |
| 267 runTests: runTests, |
| 268 loadExternalShaders: loadExternalShaders, |
| 269 |
| 270 none: false, |
| 271 }; |
| 272 }()); |
OLD | NEW |