<script src="../../resources/js-test-pre.js"></script>
<script>
  globalThis.testRunner?.waitUntilDone();

  onload = async () => {
    let adapter0 = await navigator.gpu.requestAdapter();
    let device = await adapter0.requestDevice();
    try {
      device.pushErrorScope('validation');
      let code = `
@group(0) @binding(0)
var<storage, read_write> fixedSizeArray: array<u32, 0xfffffff>;

@compute @workgroup_size(1, 1, 1)
fn compute0() {
  fixedSizeArray[0x40] = 0x11223344;
  fixedSizeArray[0x42] = 0xaabbccdd;
}
`;
      let shaderModule = device.createShaderModule({code});
      let bindGroupLayout0 = device.createBindGroupLayout({
        entries: [
          {binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: {type: 'storage'}},
        ],
      });
      let pipelineLayout = device.createPipelineLayout({
        bindGroupLayouts: [bindGroupLayout0],
      });
      let computePipeline = device.createComputePipeline({
        layout: pipelineLayout,
        compute: {module: shaderModule, entryPoint: 'compute0'},
      });
      let compilationInfo = await shaderModule.getCompilationInfo();
      for (let message of compilationInfo.messages) {
        debug(message);
      }
      let buffer0 = device.createBuffer({size: 16, usage: GPUBufferUsage.STORAGE});
      let bufferToDump = device.createBuffer({size: 16, usage: GPUBufferUsage.MAP_READ});
      let bindGroup0 = device.createBindGroup({
        layout: bindGroupLayout0,
        entries: [
          {binding: 0, resource: {buffer: buffer0, offset: 0, size: 16}},
        ],
      });
      let commandEncoder = device.createCommandEncoder();
      let computePassEncoder = commandEncoder.beginComputePass();
      computePassEncoder.setBindGroup(0, bindGroup0);
      computePassEncoder.setPipeline(computePipeline);
      computePassEncoder.dispatchWorkgroups(1, 1, 1);
      computePassEncoder.end();
      let commandBuffer = commandEncoder.finish();
      device.queue.submit([commandBuffer]);
      await device.queue.onSubmittedWorkDone();
      await bufferToDump.mapAsync(GPUMapMode.READ);
      let dataView = new DataView(bufferToDump.getMappedRange());
      for (let i = 0; i < dataView.byteLength; i += 8) {
        let v = dataView.getBigUint64(i, true);
        debug(`${i.toString(0x10).padStart(6)} ${v.toString(0x10).padStart(16)}`);
      }
    } catch (e) {
      debug('error');
      debug(e);
    } finally {
      let validationError = await device.popErrorScope();
      debug(validationError?.message);
    }
    debug('done');
    globalThis.testRunner?.notifyDone();
  };
</script>
