content/canvas/test/webgl-conformance/conformance/programs/program-test.html

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/canvas/test/webgl-conformance/conformance/programs/program-test.html	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,327 @@
     1.4 +<!--
     1.5 +Copyright (c) 2011 Mozilla Foundation. All rights reserved.
     1.6 +Use of this source code is governed by a BSD-style license that can be
     1.7 +found in the LICENSE file.
     1.8 +-->
     1.9 +<!DOCTYPE html>
    1.10 +<html>
    1.11 +<head>
    1.12 +<meta charset="utf-8">
    1.13 +<title>WebGL Program Compiling/Linking Conformance Test</title>
    1.14 +<link rel="stylesheet" href="../../resources/js-test-style.css"/>
    1.15 +<script src="../../resources/js-test-pre.js" type="text/javascript"></script>
    1.16 +<script src="../resources/webgl-test.js" type="text/javascript"></script>
    1.17 +</head>
    1.18 +<body>
    1.19 +<div id="description"></div>
    1.20 +<div id="console"></div>
    1.21 +<canvas id="canvas" width="2" height="2"> </canvas>
    1.22 +<script type="text/javascript">
    1.23 +function go() {
    1.24 +    description("Tests that program compiling/linking/using works correctly.");
    1.25 +
    1.26 +    debug("");
    1.27 +    debug("Canvas.getContext");
    1.28 +
    1.29 +    var gl = create3DContext(document.getElementById("canvas"));
    1.30 +    if (!gl) {
    1.31 +        testFailed("context does not exist");
    1.32 +        return;
    1.33 +    }
    1.34 +
    1.35 +    testPassed("context exists");
    1.36 +
    1.37 +    gl.clearColor(0.0, 0.0, 0.0, 0.0);
    1.38 +    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    1.39 +
    1.40 +    function doArraysHaveSameContents(a, b) {
    1.41 +        var flags = [];
    1.42 +        function hasUnusedValue(a, value) {
    1.43 +            for (var ii = 0; ii < a.length; ++ii) {
    1.44 +                if (a[ii] === value && !flags[ii]) {
    1.45 +                    flags[ii] = true;
    1.46 +                    return true;
    1.47 +                }
    1.48 +            }
    1.49 +            return false;
    1.50 +        }
    1.51 +
    1.52 +        try {
    1.53 +            if (a.length !== b.length) {
    1.54 +                return false;
    1.55 +            }
    1.56 +            for (var ii = 0; ii < a.length; ii++) {
    1.57 +                if (!hasUnusedValue(b, a[ii])) {
    1.58 +                    return false;
    1.59 +                }
    1.60 +            }
    1.61 +        } catch (ex) {
    1.62 +            return false;
    1.63 +        }
    1.64 +        return true;
    1.65 +    }
    1.66 +
    1.67 +/////// Check compileShader() /////////////////////////////
    1.68 +
    1.69 +    var vs = gl.createShader(gl.VERTEX_SHADER);
    1.70 +    gl.shaderSource(vs, "attribute vec4 aVertex; attribute vec4 aColor; varying vec4 vColor; void main() { vColor = aColor; gl_Position = aVertex; }");
    1.71 +    gl.compileShader(vs);
    1.72 +
    1.73 +    assertMsg(gl.getShaderParameter(vs, gl.COMPILE_STATUS) == true,
    1.74 +              "good vertex shader should compile");
    1.75 +
    1.76 +    var vs2 = gl.createShader(gl.VERTEX_SHADER);
    1.77 +    gl.shaderSource(vs2, "attribute vec4 aVertex; attribute vec4 aColor; varying vec4 vColor; void main() { vColor = aColor; gl_Position = aVertex * 0.5; }");
    1.78 +    gl.compileShader(vs2);
    1.79 +
    1.80 +    assertMsg(gl.getShaderParameter(vs2, gl.COMPILE_STATUS) == true,
    1.81 +              "good vertex shader #2 should compile");
    1.82 +
    1.83 +    var vsBad = gl.createShader(gl.VERTEX_SHADER);
    1.84 +    gl.shaderSource(vsBad, "WILL NOT COMPILE;");
    1.85 +    gl.compileShader(vsBad);
    1.86 +
    1.87 +    // GLSL 1.0.17 section 10.27. compile shader does not have to return failure.
    1.88 +    //assertMsg(gl.getShaderParameter(vsBad, gl.COMPILE_STATUS) == false,
    1.89 +    //          "bad vertex shader should fail to compile");
    1.90 +
    1.91 +    var fs = gl.createShader(gl.FRAGMENT_SHADER);
    1.92 +    gl.shaderSource(fs, "precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor; }");
    1.93 +    gl.compileShader(fs);
    1.94 +
    1.95 +    assertMsg(gl.getShaderParameter(fs, gl.COMPILE_STATUS) == true,
    1.96 +              "good fragment shader should compile");
    1.97 +
    1.98 +    var fs2 = gl.createShader(gl.FRAGMENT_SHADER);
    1.99 +    gl.shaderSource(fs2, "precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor * 0.5; }");
   1.100 +    gl.compileShader(fs2);
   1.101 +
   1.102 +    assertMsg(gl.getShaderParameter(fs2, gl.COMPILE_STATUS) == true,
   1.103 +              "good fragment shader #2 should compile");
   1.104 +
   1.105 +    var fsBad = gl.createShader(gl.FRAGMENT_SHADER);
   1.106 +    gl.shaderSource(fsBad, "WILL NOT COMPILE;");
   1.107 +    gl.compileShader(fsBad);
   1.108 +
   1.109 +    // GLSL 1.0.17 section 10.27. compile shader does not have to return failure.
   1.110 +    //assertMsg(gl.getShaderParameter(fsBad, gl.COMPILE_STATUS) == false,
   1.111 +    //          "bad fragment shader should fail to compile");
   1.112 +
   1.113 +    glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors at this point");
   1.114 +
   1.115 +/////// Check attachShader() /////////////////////////////
   1.116 +
   1.117 +    function checkAttachShader(already_attached_shaders, shader, expected_error_code, errmsg) {
   1.118 +        var prog = gl.createProgram();
   1.119 +        for (var i = 0; i < already_attached_shaders.length; ++i)
   1.120 +            gl.attachShader(prog, already_attached_shaders[i]);
   1.121 +        if(gl.getError() != gl.NO_ERROR)
   1.122 +            assertMsg(false, "unexpected error in attachShader()");
   1.123 +        gl.attachShader(prog, shader);
   1.124 +        glErrorShouldBe(gl, expected_error_code, errmsg);
   1.125 +    }
   1.126 +
   1.127 +    checkAttachShader([], vs, gl.NO_ERROR, "attaching a vertex shader should succeed");
   1.128 +    checkAttachShader([vs], vs, gl.INVALID_OPERATION,
   1.129 +                      "attaching an already attached vertex shader should generate INVALID_OPERATION");
   1.130 +    checkAttachShader([], fs, gl.NO_ERROR, "attaching a fragment shader should succeed");
   1.131 +    checkAttachShader([fs], fs, gl.INVALID_OPERATION,
   1.132 +                      "attaching an already attached fragment shader should generate INVALID_OPERATION");
   1.133 +    checkAttachShader([vs], vs2, gl.INVALID_OPERATION,
   1.134 +                      "attaching shaders of the same type to a program should generate INVALID_OPERATION");
   1.135 +    checkAttachShader([fs], fs2, gl.INVALID_OPERATION,
   1.136 +                      "attaching shaders of the same type to a program should generate INVALID_OPERATION");
   1.137 +
   1.138 +/////// Check detachShader() /////////////////////////////
   1.139 +
   1.140 +    function checkDetachShader(already_attached_shaders, shader, expected_error_code, errmsg) {
   1.141 +        var prog = gl.createProgram();
   1.142 +        for (var i = 0; i < already_attached_shaders.length; ++i)
   1.143 +            gl.attachShader(prog, already_attached_shaders[i]);
   1.144 +        if(gl.getError() != gl.NO_ERROR)
   1.145 +            assertMsg(false, "unexpected error in attachShader()");
   1.146 +        gl.detachShader(prog, shader);
   1.147 +        glErrorShouldBe(gl, expected_error_code, errmsg);
   1.148 +    }
   1.149 +
   1.150 +    checkDetachShader([vs], vs, gl.NO_ERROR, "detaching a vertex shader should succeed");
   1.151 +    checkDetachShader([fs], vs, gl.INVALID_OPERATION,
   1.152 +                      "detaching a not already attached vertex shader should generate INVALID_OPERATION");
   1.153 +    checkDetachShader([fs], fs, gl.NO_ERROR, "detaching a fragment shader should succeed");
   1.154 +    checkDetachShader([vs], fs, gl.INVALID_OPERATION,
   1.155 +                      "detaching a not already attached fragment shader should generate INVALID_OPERATION");
   1.156 +
   1.157 +/////// Check getAttachedShaders() /////////////////////////////
   1.158 +
   1.159 +    function checkGetAttachedShaders(shaders_to_attach, shaders_to_detach, expected_shaders, errmsg) {
   1.160 +        var prog = gl.createProgram();
   1.161 +        for (var i = 0; i < shaders_to_attach.length; ++i)
   1.162 +            gl.attachShader(prog, shaders_to_attach[i]);
   1.163 +        if(gl.getError() != gl.NO_ERROR)
   1.164 +            assertMsg(false, "unexpected error in attachShader()");
   1.165 +        for (var i = 0; i < shaders_to_detach.length; ++i)
   1.166 +            gl.detachShader(prog, shaders_to_detach[i]);
   1.167 +        if(gl.getError() != gl.NO_ERROR)
   1.168 +            assertMsg(false, "unexpected error in detachShader()");
   1.169 +        assertMsg(doArraysHaveSameContents(gl.getAttachedShaders(prog), expected_shaders), errmsg);
   1.170 +    }
   1.171 +    checkGetAttachedShaders([], [], [], "getAttachedShaders should return an empty list by default");
   1.172 +    checkGetAttachedShaders([fs], [], [fs], "attaching a single shader should give the expected list");
   1.173 +    checkGetAttachedShaders([fs, vs], [], [fs, vs],
   1.174 +        "attaching some shaders should give the expected list");
   1.175 +    checkGetAttachedShaders([fs], [fs], [], "attaching a shader and detaching it shoud leave an empty list");
   1.176 +    checkGetAttachedShaders([fs, vs], [fs, vs], [],
   1.177 +        "attaching some shaders and detaching them in same order shoud leave an empty list");
   1.178 +    checkGetAttachedShaders([fs, vs], [vs, fs], [],
   1.179 +        "attaching some shaders and detaching them in random order shoud leave an empty list");
   1.180 +    checkGetAttachedShaders([fs, vs], [vs], [fs],
   1.181 +        "attaching and detaching some shaders should leave the difference list");
   1.182 +    checkGetAttachedShaders([fs, vs], [fs], [vs],
   1.183 +        "attaching and detaching some shaders should leave the difference list");
   1.184 +    checkGetAttachedShaders([fsBad], [], [fsBad],
   1.185 +        "attaching a shader that failed to compile should still show it in the list");
   1.186 +    checkGetAttachedShaders([fs, vsBad], [], [fs, vsBad],
   1.187 +        "attaching shaders, including one that failed to compile, should still show the it in the list");
   1.188 +
   1.189 +/////// Check linkProgram() and useProgram /////////////////////////////
   1.190 +
   1.191 +    function checkLinkAndUse(shaders, deleteShaderAfterAttach, expected_status, errmsg) {
   1.192 +        var prog = gl.createProgram();
   1.193 +        for (var i = 0; i < shaders.length; ++i) {
   1.194 +            gl.attachShader(prog, shaders[i]);
   1.195 +            if (deleteShaderAfterAttach)
   1.196 +                gl.deleteShader(shaders[i]);
   1.197 +        }
   1.198 +        gl.bindAttribLocation(prog, 0, "aVertex");
   1.199 +        gl.bindAttribLocation(prog, 1, "aColor");
   1.200 +        gl.linkProgram(prog);
   1.201 +        if (gl.getError() != gl.NO_ERROR)
   1.202 +            assertMsg(false, "unexpected error in linkProgram()");
   1.203 +        assertMsg(gl.getProgramParameter(prog, gl.LINK_STATUS) == expected_status, errmsg);
   1.204 +        var infolog = gl.getProgramInfoLog(prog);
   1.205 +        if (gl.getError() != gl.NO_ERROR)
   1.206 +            assertMsg(false, "unexpected error in getProgramInfoLog()");
   1.207 +        if (typeof(infolog) != "string")
   1.208 +            assertMsg(false, "getProgramInfoLog() did not return a string");
   1.209 +        if (expected_status == true && gl.getProgramParameter(prog, gl.LINK_STATUS) == false)
   1.210 +            debug(infolog);
   1.211 +        if (gl.getError() != gl.NO_ERROR)
   1.212 +            assertMsg(false, "unexpected error in getProgramParameter()");
   1.213 +        gl.useProgram(prog);
   1.214 +        if (expected_status == true)
   1.215 +            glErrorShouldBe(gl, gl.NO_ERROR, "using a valid program should succeed");
   1.216 +        if (expected_status == false)
   1.217 +            glErrorShouldBe(gl, gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
   1.218 +        return prog;
   1.219 +    }
   1.220 +
   1.221 +    var progGood1 = checkLinkAndUse([vs, fs], false, true, "valid program should link");
   1.222 +    var progGood2 = checkLinkAndUse([vs, fs2], false, true, "valid program #2 should link");
   1.223 +    var progBad1 = checkLinkAndUse([vs], false, false, "program with no fragment shader should fail to link");
   1.224 +    var progBad2 = checkLinkAndUse([fs], false, false, "program with no vertex shader should fail to link");
   1.225 +    var progBad3 = checkLinkAndUse([vsBad, fs], false, false, "program with bad vertex shader should fail to link");
   1.226 +    var progBad4 = checkLinkAndUse([vs, fsBad], false, false, "program with bad fragment shader should fail to link");
   1.227 +    var progBad5 = checkLinkAndUse([vsBad, fsBad], false, false, "program with bad shaders should fail to link");
   1.228 +
   1.229 +    gl.useProgram(progGood1);
   1.230 +    glErrorShouldBe(gl, gl.NO_ERROR, "using a valid program shouldn't generate a GL error");
   1.231 +
   1.232 +    var vbuf = gl.createBuffer();
   1.233 +    gl.bindBuffer(gl.ARRAY_BUFFER, vbuf);
   1.234 +    gl.bufferData(gl.ARRAY_BUFFER,
   1.235 +                  new Float32Array([
   1.236 +                      0.0, 0.0, 0.0, 1.0,
   1.237 +                      1.0, 0.0, 0.0, 1.0,
   1.238 +                      1.0, 1.0, 0.0, 1.0,
   1.239 +                      0.0, 1.0, 0.0, 1.0]),
   1.240 +                  gl.STATIC_DRAW);
   1.241 +    gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0);
   1.242 +    gl.enableVertexAttribArray(0);
   1.243 +    gl.vertexAttrib3f(1, 1.0, 0.0, 0.0);
   1.244 +
   1.245 +    glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors at this point #2");
   1.246 +
   1.247 +    gl.useProgram(progGood1);
   1.248 +    gl.drawArrays(gl.TRIANGLES, 0, 3);
   1.249 +    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid program shouldn't generate a GL error");
   1.250 +
   1.251 +    gl.useProgram(progBad1);
   1.252 +    glErrorShouldBe(gl, gl.INVALID_OPERATION, "using an invalid program should generate INVALID_OPERATION");
   1.253 +    gl.drawArrays(gl.TRIANGLES, 0, 3);
   1.254 +    glErrorShouldBe(gl, gl.NO_ERROR, "Try to use an invalid program should not change the current rendering state");
   1.255 +
   1.256 +    gl.useProgram(progGood2);
   1.257 +    gl.drawArrays(gl.TRIANGLES, 0, 3);
   1.258 +    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid program shouldn't generate a GL error");
   1.259 +    gl.detachShader(progGood2, fs2);
   1.260 +    gl.attachShader(progGood2, fsBad);
   1.261 +    gl.linkProgram(progGood2);
   1.262 +    assertMsg(gl.getProgramParameter(progGood2, gl.LINK_STATUS) == false,
   1.263 +              "linking should fail with in-use formerly good program, with new bad shader attached");
   1.264 +
   1.265 +    // Invalid link leaves previous valid program intact.
   1.266 +    gl.drawArrays(gl.TRIANGLES, 0, 3);
   1.267 +    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid program shouldn't generate a GL error");
   1.268 +
   1.269 +    gl.useProgram(progGood1);
   1.270 +    gl.drawArrays(gl.TRIANGLES, 0, 4);
   1.271 +    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid when last used program shouldn't generate a GL error");
   1.272 +
   1.273 +    var progGood1 = checkLinkAndUse([vs, fs], true, true, "delete shaders after attaching them and before linking program should not affect linkProgram");
   1.274 +    gl.useProgram(progGood1);
   1.275 +    gl.drawArrays(gl.TRIANGLES, 0, 4);
   1.276 +    glErrorShouldBe(gl, gl.NO_ERROR, "drawing with a valid when last used program shouldn't generate a GL error");
   1.277 +
   1.278 +/////// Check deleteProgram() and deleteShader() /////////////////////////////
   1.279 +
   1.280 +    gl.useProgram(progGood1);
   1.281 +    gl.deleteProgram(progGood1);
   1.282 +    gl.drawArrays(gl.TRIANGLES, 0, 4);
   1.283 +    glErrorShouldBe(gl, gl.NO_ERROR, "delete the current program shouldn't change the current rendering state");
   1.284 +
   1.285 +    gl.linkProgram(progGood1);
   1.286 +    glErrorShouldBe(gl, gl.NO_ERROR, "The current program shouldn't be deleted");
   1.287 +
   1.288 +    var fs3 = gl.createShader(gl.FRAGMENT_SHADER);
   1.289 +    gl.shaderSource(fs3, "precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor; }");
   1.290 +    gl.compileShader(fs3);
   1.291 +
   1.292 +    assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
   1.293 +              "good fragment shader should compile");
   1.294 +
   1.295 +    gl.deleteShader(fs3);
   1.296 +    gl.compileShader(fs3);
   1.297 +    glErrorShouldBe(gl, gl.INVALID_VALUE, "an unattached shader should be deleted immediately");
   1.298 +
   1.299 +    fs3 = gl.createShader(gl.FRAGMENT_SHADER);
   1.300 +    gl.shaderSource(fs3, "precision mediump float; varying vec4 vColor; void main() { gl_FragColor = vColor; }");
   1.301 +    gl.compileShader(fs3);
   1.302 +
   1.303 +    assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
   1.304 +              "good fragment shader should compile");
   1.305 +
   1.306 +    gl.detachShader(progGood1, fs);
   1.307 +    gl.attachShader(progGood1, fs3);
   1.308 +
   1.309 +    gl.deleteShader(fs3);
   1.310 +    gl.compileShader(fs3);
   1.311 +    assertMsg(gl.getShaderParameter(fs3, gl.COMPILE_STATUS) == true,
   1.312 +              "an attached shader shouldn't be deleted");
   1.313 +
   1.314 +    gl.useProgram(null);
   1.315 +    gl.linkProgram(progGood1);
   1.316 +    glErrorShouldBe(gl, gl.INVALID_VALUE, "a delete-marked program should be deleted once it's no longer the current program");
   1.317 +
   1.318 +    gl.compileShader(fs3);
   1.319 +    glErrorShouldBe(gl, gl.INVALID_VALUE, "a delete-marked shader should be deleted once all its attachments are removed");
   1.320 +}
   1.321 +
   1.322 +debug("");
   1.323 +go();
   1.324 +
   1.325 +successfullyParsed = true;
   1.326 +</script>
   1.327 +<script>finishTest();</script>
   1.328 +
   1.329 +</body>
   1.330 +</html>

mercurial