summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/api/operation/command_buffer/copyBufferToBuffer.spec.ts
blob: c7cae61d793b6f9145d83e448e80110bf2bcfb80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
export const description = 'copyBufferToBuffer operation tests';

import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { GPUTest } from '../../../gpu_test.js';

export const g = makeTestGroup(GPUTest);

g.test('single')
  .desc(
    `Validate the correctness of the copy by filling the srcBuffer with testable data, doing
  CopyBufferToBuffer() copy, and verifying the content of the whole dstBuffer with MapRead:
  Copy {4 bytes, part of, the whole} srcBuffer to the dstBuffer {with, without} a non-zero valid
  srcOffset that
  - covers the whole dstBuffer
  - covers the beginning of the dstBuffer
  - covers the end of the dstBuffer
  - covers neither the beginning nor the end of the dstBuffer`
  )
  .paramsSubcasesOnly(u =>
    u //
      .combine('srcOffset', [0, 4, 8, 16])
      .combine('dstOffset', [0, 4, 8, 16])
      .combine('copySize', [0, 4, 8, 16])
      .expand('srcBufferSize', p => [p.srcOffset + p.copySize, p.srcOffset + p.copySize + 8])
      .expand('dstBufferSize', p => [p.dstOffset + p.copySize, p.dstOffset + p.copySize + 8])
  )
  .fn(async t => {
    const { srcOffset, dstOffset, copySize, srcBufferSize, dstBufferSize } = t.params;

    const srcData = new Uint8Array(srcBufferSize);
    for (let i = 0; i < srcBufferSize; ++i) {
      srcData[i] = i + 1;
    }

    const src = t.makeBufferWithContents(srcData, GPUBufferUsage.COPY_SRC);

    const dst = t.device.createBuffer({
      size: dstBufferSize,
      usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
    });
    t.trackForCleanup(dst);

    const encoder = t.device.createCommandEncoder();
    encoder.copyBufferToBuffer(src, srcOffset, dst, dstOffset, copySize);
    t.device.queue.submit([encoder.finish()]);

    const expectedDstData = new Uint8Array(dstBufferSize);
    for (let i = 0; i < copySize; ++i) {
      expectedDstData[dstOffset + i] = srcData[srcOffset + i];
    }

    t.expectGPUBufferValuesEqual(dst, expectedDstData);
  });

g.test('state_transitions')
  .desc(
    `Test proper state transitions/barriers happen between copy commands.
    Copy part of src to dst, then a different part of dst to src, and check contents of both.`
  )
  .fn(async t => {
    const srcData = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
    const dstData = new Uint8Array([10, 20, 30, 40, 50, 60, 70, 80]);

    const src = t.makeBufferWithContents(
      srcData,
      GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
    );
    const dst = t.makeBufferWithContents(
      dstData,
      GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
    );

    const encoder = t.device.createCommandEncoder();
    encoder.copyBufferToBuffer(src, 0, dst, 4, 4);
    encoder.copyBufferToBuffer(dst, 0, src, 4, 4);
    t.device.queue.submit([encoder.finish()]);

    const expectedSrcData = new Uint8Array([1, 2, 3, 4, 10, 20, 30, 40]);
    const expectedDstData = new Uint8Array([10, 20, 30, 40, 1, 2, 3, 4]);
    t.expectGPUBufferValuesEqual(src, expectedSrcData);
    t.expectGPUBufferValuesEqual(dst, expectedDstData);
  });

g.test('copy_order')
  .desc(
    `Test copy commands in one command buffer occur in the correct order.
    First copies one region from src to dst, then another region from src to an overlapping region
    of dst, then checks the dst buffer's contents.`
  )
  .fn(async t => {
    const srcData = new Uint32Array([1, 2, 3, 4, 5, 6, 7, 8]);

    const src = t.makeBufferWithContents(srcData, GPUBufferUsage.COPY_SRC);

    const dst = t.device.createBuffer({
      size: srcData.length * 4,
      usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
    });
    t.trackForCleanup(dst);

    const encoder = t.device.createCommandEncoder();
    encoder.copyBufferToBuffer(src, 0, dst, 0, 16);
    encoder.copyBufferToBuffer(src, 16, dst, 8, 16);
    t.device.queue.submit([encoder.finish()]);

    const expectedDstData = new Uint32Array([1, 2, 5, 6, 7, 8, 0, 0]);
    t.expectGPUBufferValuesEqual(dst, expectedDstData);
  });