1export const description = '';
2
3import { pbool, params } from '../../../../common/framework/params_builder.js';
4import { makeTestGroup } from '../../../../common/framework/test_group.js';
5import { assert } from '../../../../common/framework/util/util.js';
6
7import { MappingTest } from './mapping_test.js';
8
9export const g = makeTestGroup(MappingTest);
10
11const kCases = [
12  { size: 0, range: [] },
13  { size: 0, range: [undefined] },
14  { size: 0, range: [undefined, undefined] },
15  { size: 0, range: [0] },
16  { size: 0, range: [0, undefined] },
17  { size: 0, range: [0, 0] },
18  { size: 12, range: [] },
19  { size: 12, range: [undefined] },
20  { size: 12, range: [undefined, undefined] },
21  { size: 12, range: [0] },
22  { size: 12, range: [0, undefined] },
23  { size: 12, range: [0, 12] },
24  { size: 12, range: [0, 0] },
25  { size: 12, range: [8] },
26  { size: 12, range: [8, undefined] },
27  { size: 12, range: [8, 4] },
28  { size: 28, range: [8, 8] },
29  { size: 28, range: [8, 12] },
30  { size: 512 * 1024, range: [] },
31];
32
33function reifyMapRange(bufferSize: number, range: (number | undefined)[]): [number, number] {
34  const offset = range[0] ?? 0;
35  return [offset, range[1] ?? bufferSize - offset];
36}
37
38g.test('mapAsync,write')
39  .params(kCases)
40  .fn(async t => {
41    const { size, range } = t.params;
42    const [rangeOffset, rangeSize] = reifyMapRange(size, range);
43
44    const buffer = t.device.createBuffer({
45      size,
46      usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.MAP_WRITE,
47    });
48
49    await buffer.mapAsync(GPUMapMode.WRITE);
50    const arrayBuffer = buffer.getMappedRange(...range);
51    t.checkMapWrite(buffer, rangeOffset, arrayBuffer, rangeSize);
52  });
53
54g.test('mapAsync,read')
55  .params(kCases)
56  .fn(async t => {
57    const { size, range } = t.params;
58    const [, rangeSize] = reifyMapRange(size, range);
59
60    const buffer = t.device.createBuffer({
61      mappedAtCreation: true,
62      size,
63      usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
64    });
65    const init = buffer.getMappedRange(...range);
66
67    assert(init.byteLength === rangeSize);
68    const expected = new Uint32Array(new ArrayBuffer(rangeSize));
69    const data = new Uint32Array(init);
70    for (let i = 0; i < data.length; ++i) {
71      data[i] = expected[i] = i + 1;
72    }
73    buffer.unmap();
74
75    await buffer.mapAsync(GPUMapMode.READ);
76    const actual = new Uint8Array(buffer.getMappedRange(...range));
77    t.expectBuffer(actual, new Uint8Array(expected.buffer));
78  });
79
80g.test('mappedAtCreation')
81  .params(
82    params()
83      .combine(kCases) //
84      .combine(pbool('mappable'))
85  )
86  .fn(async t => {
87    const { size, range, mappable } = t.params;
88    const [, rangeSize] = reifyMapRange(size, range);
89
90    const buffer = t.device.createBuffer({
91      mappedAtCreation: true,
92      size,
93      usage: GPUBufferUsage.COPY_SRC | (mappable ? GPUBufferUsage.MAP_WRITE : 0),
94    });
95    const arrayBuffer = buffer.getMappedRange(...range);
96    t.checkMapWrite(buffer, range[0] ?? 0, arrayBuffer, rangeSize);
97  });
98