| <!-- |
| Copyright (c) 2021 The Khronos Group Inc. |
| Use of this source code is governed by an MIT-style license that can be |
| found in the LICENSE.txt file. |
| --> |
| |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <title>WebGL GLSL Conformance Tests - Swizzle as lvalue</title> |
| <link rel="stylesheet" href="../../../../webgl_test_files/resources/js-test-style.css"/> |
| <link rel="stylesheet" href="../../../../webgl_test_files/resources/glsl-feature-tests.css"/> |
| <script src="../../../../webgl_test_files/js/js-test-pre.js"></script> |
| <script src="../../../../webgl_test_files/js/webgl-test-utils.js"></script> |
| <script src="../../../../webgl_test_files/js/glsl-conformance-test.js"></script> |
| </head> |
| <body> |
| <div id="description"></div> |
| <div id="console"></div> |
| <!-- |
| Tests swizzle lvalues with out and inout function parameters. |
| 6.1.1 Function Calling Conventions |
| Evaluation of an inout parameter results in both a value and an l-value; the value is copied to |
| the formal parameter at call time and the l- value is used to copy out a value when the function |
| returns. |
| --> |
| <script id="fs0" type="text/something-not-javascript"> |
| precision mediump float; |
| void f(out $dim v) { |
| v = $ref; |
| } |
| void main() |
| { |
| vec4 i = vec4(10., 11., 12., 13.); |
| f(i.$components); |
| bool correct = false; |
| if (i == $result) |
| correct = true; |
| gl_FragColor = vec4(0, correct ? 1. : 0., 0., 1.); |
| } |
| </script> |
| <script id="fs1" type="text/something-not-javascript"> |
| precision mediump float; |
| void f(inout $dim v) { |
| v += $ref; |
| } |
| void main() |
| { |
| vec4 i = vec4(10., 11., 12., 13.); |
| f(i.$components); |
| bool correct = false; |
| if (i == $resultInOut) |
| correct = true; |
| gl_FragColor = vec4(0, correct ? 1. : 0., 0., 1.); |
| } |
| </script> |
| <script> |
| "use strict"; |
| |
| description(); |
| |
| // GLSL ES 3.00.6 5.5 Vector Components |
| // To form an l-value, swizzling must be applied to an l-value of vector type, contain no duplicate |
| // components, and it results in an l-value of scalar or vector type, depending on number of |
| // components specified. |
| function computeLValueSwizzles() { |
| let results = []; |
| function f(components, swizzle) { |
| for (let c of components) { |
| results.push(swizzle.concat([c])); |
| let rest = components.filter((e) => { return e != c; }); |
| if (rest) |
| f(rest, swizzle.concat([c])); |
| } |
| } |
| f([0, 1, 2, 3], []); |
| return results; |
| } |
| |
| var swizzles = computeLValueSwizzles(); |
| |
| // Sanity check that computing the swizzles produces something to test. |
| shouldBe("swizzles.length", "64"); |
| shouldBe("components(swizzles[0])", "'r'"); |
| shouldBe("components(swizzles[swizzles.length - 1])", "'abgr'"); |
| |
| var refValue = [ "1.", "2.", "3.", "4." ]; |
| |
| var init = [ "10.", "11.", "12.", "13." ]; |
| |
| function dim(swizzle) { |
| if (swizzle.length == 1) |
| return 'float' |
| return `vec${swizzle.length}`; |
| } |
| |
| function result(swizzle) { |
| let a = init.map((e, c) => { |
| if (swizzle.includes(c)) |
| return refValue[c]; |
| return e; |
| }); |
| return `vec4(${a.join(', ')})`; |
| } |
| |
| function resultInOut(swizzle) { |
| let a = init.map((e, c) => { |
| if (swizzle.includes(c)) |
| return `${e} + ${refValue[c]}`; |
| return e; |
| }); |
| return `vec4(${a.join(', ')})`; |
| } |
| |
| function ref(swizzle) { |
| let a = swizzle.map((c) => { return refValue[c]; }); |
| return `${dim(swizzle)}(${a.join(', ')})`; |
| } |
| |
| function components(swizzle) { |
| return swizzle.map((e) => { return 'rgba'[e]; }).join(''); |
| } |
| |
| var tests = []; |
| for (var swizzle of swizzles) { |
| for (var ii = 0; ii < 2; ++ii) { |
| var fsrc = document.getElementById("fs" + ii).text; |
| fsrc = fsrc.replace(/\$dim/g, dim(swizzle)) |
| .replace(/\$resultInOut/g, resultInOut(swizzle)) |
| .replace(/\$result/g, result(swizzle)) |
| .replace(/\$ref/g, ref(swizzle)) |
| .replace(/\$components/g, components(swizzle)); |
| tests.push({ |
| fShaderSource: fsrc, |
| fShaderSuccess: true, |
| linkSuccess: true, |
| passMsg: `Swizzle as lvalue works, func: ${ii}, swizzle: ${components(swizzle)}` |
| }); |
| } |
| } |
| |
| GLSLConformanceTester.runRenderTests(tests); |
| </script> |
| </body> |
| </html> |