tor-browser

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

entry_points.spec.ts (2422B)


      1 export const description = `
      2 Stress tests covering behavior around shader entry points.
      3 `;
      4 
      5 import { makeTestGroup } from '../../common/framework/test_group.js';
      6 import { range } from '../../common/util/util.js';
      7 import { GPUTest } from '../../webgpu/gpu_test.js';
      8 
      9 export const g = makeTestGroup(GPUTest);
     10 
     11 const makeCode = (numEntryPoints: number) => {
     12  const kBaseCode = `
     13      struct Buffer { data: u32, };
     14      @group(0) @binding(0) var<storage, read_write> buffer: Buffer;
     15      fn main() { buffer.data = buffer.data + 1u;  }
     16      `;
     17  const makeEntryPoint = (i: number) => `
     18      @compute @workgroup_size(1) fn computeMain${i}() { main(); }
     19      `;
     20  return kBaseCode + range(numEntryPoints, makeEntryPoint).join('');
     21 };
     22 
     23 g.test('many')
     24  .desc(
     25    `Tests compilation and usage of shaders with a huge number of entry points.
     26 
     27 TODO: There may be a normative limit to the number of entry points allowed in
     28 a shader, in which case this would become a validation test instead.`
     29  )
     30  .fn(t => {
     31    const data = new Uint32Array([0]);
     32    const buffer = t.makeBufferWithContents(data, GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC);
     33 
     34    // NOTE: Initial shader compilation time seems to scale exponentially with
     35    // this value in Chrome.
     36    const kNumEntryPoints = 200;
     37 
     38    const shader = t.device.createShaderModule({
     39      code: makeCode(kNumEntryPoints),
     40    });
     41 
     42    const layout = t.device.createBindGroupLayout({
     43      entries: [
     44        {
     45          binding: 0,
     46          visibility: GPUShaderStage.COMPUTE,
     47          buffer: { type: 'storage' },
     48        },
     49      ],
     50    });
     51    const pipelineLayout = t.device.createPipelineLayout({
     52      bindGroupLayouts: [layout],
     53    });
     54    const bindGroup = t.device.createBindGroup({
     55      layout,
     56      entries: [{ binding: 0, resource: { buffer } }],
     57    });
     58 
     59    const encoder = t.device.createCommandEncoder();
     60    range(kNumEntryPoints, i => {
     61      const pipeline = t.device.createComputePipeline({
     62        layout: pipelineLayout,
     63        compute: {
     64          module: shader,
     65          entryPoint: `computeMain${i}`,
     66        },
     67      });
     68 
     69      const pass = encoder.beginComputePass();
     70      pass.setPipeline(pipeline);
     71      pass.setBindGroup(0, bindGroup);
     72      pass.dispatchWorkgroups(1);
     73      pass.end();
     74    });
     75 
     76    t.device.queue.submit([encoder.finish()]);
     77    t.expectGPUBufferValuesEqual(buffer, new Uint32Array([kNumEntryPoints]));
     78  });