Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / glsl3 / texture-bias.html
blob0c30eb7129ce21707db82416c60ad0cf9c913f33
1 <!--
2 Copyright (c) 2022 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 texture bias 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 <script src="../../js/glsl-conformance-test.js"></script>
16 </head>
17 <body>
18 <div id="description"></div>
19 <div id="console"></div>
20 <script>
21 "use strict";
22 description("Texture bias should both function and respect limits.");
24 function runTest(gl) {
25 // no if idea any drivers have a giant limit like 2^32 so just in case.
26 const kMaxMaxTextureSize = 256 * 1024 * 1024;
27 const maxTextureSize = Math.min(kMaxMaxTextureSize, gl.getParameter(gl.MAX_TEXTURE_SIZE));
28 const maxLODs = (Math.log2(maxTextureSize) | 0) + 1;
29 const maxTextureLODBias = gl.getParameter(gl.MAX_TEXTURE_LOD_BIAS);
31 debug(`maxTextureSize: ${maxTextureSize}`);
32 debug(`maxLODs: ${maxLODs}`);
33 debug(`maxTextureLODBias: ${maxTextureLODBias}`);
35 const vs = `#version 300 es
36 uniform float uvMult;
37 out vec2 v_uv;
38 void main() {
39 vec2 xy = vec2(
40 gl_VertexID % 2,
41 (gl_VertexID / 2 + gl_VertexID / 3) % 2);
43 gl_Position = vec4(xy * 2. - 1.0, 0, 1);
44 v_uv = xy * uvMult;
47 const fs = `#version 300 es
48 precision highp float;
49 uniform sampler2D tex;
50 uniform float biasMult;
51 in vec2 v_uv;
52 out vec4 fragColor;
53 void main() {
54 vec4 texColor = texture(tex, v_uv, (gl_FragCoord.x - 0.5) * biasMult); // the color we care about
55 vec4 texelColor = texelFetch(tex, ivec2(0), int(gl_FragCoord)); // just a sanity check
56 vec4 coordColor = vec4((100.0 + gl_FragCoord.x - 0.5) / 255.0); // another sanity check
57 fragColor = mix(texColor, coordColor, step(1.0, gl_FragCoord.y)); // line < 1 = texColor, line >= 1 = coordColor
58 fragColor = mix(fragColor, texelColor, step(2.0, gl_FragCoord.y)); // line < 2 = fragColor, line >= 2 = texelColor
61 const program = wtu.setupProgram(gl, [vs, fs]);
62 const uvMultLoc = gl.getUniformLocation(program, 'uvMult');
63 const biasLoc = gl.getUniformLocation(program, 'biasMult');
65 gl.canvas.width = maxLODs;
66 gl.canvas.height = 3;
67 gl.viewport(0, 0, maxLODs, 3);
69 // create a texture where each mip is a different color (1, 2, 3, ...)
70 const tex = gl.createTexture();
71 gl.bindTexture(gl.TEXTURE_2D, tex);
72 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
73 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
74 gl.texStorage2D(gl.TEXTURE_2D, maxLODs, gl.RGBA8, maxTextureSize, 1);
76 let level = 0;
77 for (let width = maxTextureSize; width > 0; width = width / 2 | 0) {
78 const pixels = new Uint8Array(width * 1 * 4);
79 pixels.fill(level + 1);
80 debug(`fill mip level: ${level}, width: ${width}`);
81 gl.texSubImage2D(gl.TEXTURE_2D, level, 0, 0, width, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
82 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
83 ++level;
87 // Draw each mip. Result should be [mip0, mip1, mip2, ...]
88 debug("");
89 debug("check positive bias");
90 // set the UVs so we'd get mip level 0 for every pixel
91 gl.uniform1f(uvMultLoc, maxLODs / maxTextureSize);
92 gl.uniform1f(biasLoc, 1);
93 gl.drawArrays(gl.TRIANGLES, 0, 6);
95 wtu.glErrorShouldBe(gl, gl.NO_ERROR);
97 const clampPlusMinus = (v, limit) => Math.min(limit, Math.max(-limit, v));
99 const checkResults = (gl, biasMult) => {
100 const base = biasMult > 0 ? 1 : maxLODs;
101 for (let i = 0; i < maxLODs; ++i) {
103 const expected = new Array(4).fill(clampPlusMinus(i * biasMult, maxTextureLODBias) + base);
104 wtu.checkCanvasRect(gl, i, 0, 1, 1, expected, `should be: ${expected}`);
107 const expected = new Array(4).fill(100 + i);
108 wtu.checkCanvasRect(gl, i, 1, 1, 1, expected, `should be: ${expected}`);
111 const expected = new Array(4).fill(i + 1);
112 wtu.checkCanvasRect(gl, i, 2, 1, 1, expected, `should be: ${expected}`);
117 checkResults(gl, 1);
119 // Draw each mip. Result should be [mipMax, mipMax - 1, mipMax - 2, ...]
120 debug("");
121 debug("check negative bias");
122 // set the UVs so we'd get highest mip level (the 1x1 level mip) for every pixel
123 gl.uniform1f(uvMultLoc, maxLODs);
124 gl.uniform1f(biasLoc, -1);
125 gl.drawArrays(gl.TRIANGLES, 0, 6);
127 checkResults(gl, -1);
129 finishTest();
132 const wtu = WebGLTestUtils;
134 const gl = wtu.create3DContext(undefined, undefined, 2);
136 var successfullyParsed = true;
138 if (!gl) {
139 testFailed("Unable to initialize WebGL 2.0 context.");
140 } else {
141 runTest(gl);
144 </script>
145 </body>
146 </html>