tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

texture-bias.html (4790B)


      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 -->
      6 
      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.");
     23 
     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);
     30 
     31  debug(`maxTextureSize: ${maxTextureSize}`);
     32  debug(`maxLODs: ${maxLODs}`);
     33  debug(`maxTextureLODBias: ${maxTextureLODBias}`);
     34 
     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);
     42 
     43    gl_Position = vec4(xy * 2. - 1.0, 0, 1);
     44    v_uv = xy * uvMult;
     45  }
     46  `;
     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
     59  }
     60  `;
     61  const program = wtu.setupProgram(gl, [vs, fs]);
     62  const uvMultLoc = gl.getUniformLocation(program, 'uvMult');
     63  const biasLoc = gl.getUniformLocation(program, 'biasMult');
     64 
     65  gl.canvas.width = maxLODs;
     66  gl.canvas.height = 3;
     67  gl.viewport(0, 0, maxLODs, 3);
     68 
     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);
     75  {
     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;
     84    }
     85  }
     86 
     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);
     94 
     95  wtu.glErrorShouldBe(gl, gl.NO_ERROR);
     96 
     97  const clampPlusMinus = (v, limit) => Math.min(limit, Math.max(-limit, v));
     98 
     99  const checkResults = (gl, biasMult) => {
    100    const base = biasMult > 0 ? 1 : maxLODs;
    101    for (let i = 0; i < maxLODs; ++i) {
    102      {
    103        const expected = new Array(4).fill(clampPlusMinus(i * biasMult, maxTextureLODBias) + base);
    104        wtu.checkCanvasRect(gl, i, 0, 1, 1, expected, `should be: ${expected}`);
    105      }
    106      {
    107        const expected = new Array(4).fill(100 + i);
    108        wtu.checkCanvasRect(gl, i, 1, 1, 1, expected, `should be: ${expected}`);
    109      }
    110      {
    111        const expected = new Array(4).fill(i + 1);
    112        wtu.checkCanvasRect(gl, i, 2, 1, 1, expected, `should be: ${expected}`);
    113      }
    114    }
    115  }
    116 
    117  checkResults(gl, 1);
    118 
    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);
    126 
    127  checkResults(gl, -1);
    128 
    129  finishTest();
    130 }
    131 
    132 const wtu = WebGLTestUtils;
    133 
    134 const gl = wtu.create3DContext(undefined, undefined, 2);
    135 
    136 var successfullyParsed = true;
    137 
    138 if (!gl) {
    139  testFailed("Unable to initialize WebGL 2.0 context.");
    140 } else {
    141  runTest(gl);
    142 }
    143 
    144 </script>
    145 </body>
    146 </html>