Skip to content

Commit

Permalink
port Austin's buffer mapping tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kainino0x committed Aug 2, 2019
1 parent cd0ce75 commit 0206834
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 72 deletions.
18 changes: 0 additions & 18 deletions src/suites/cts/buffers/createBufferMapped.spec.ts

This file was deleted.

35 changes: 35 additions & 0 deletions src/suites/cts/buffers/create_mapped.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export const description = ``;

import { TestGroup, pbool, pcombine, poptions } from '../../../framework/index.js';

import { MappingTest } from './mapping_test.js';

export const g = new TestGroup(MappingTest);

g.test('createBufferMapped', async t => {
const size = t.params.size;
const [buffer, arrayBuffer] = t.device.createBufferMapped({
size,
usage: GPUBufferUsage.COPY_SRC | (t.params.mappable ? GPUBufferUsage.MAP_WRITE : 0),
});
await t.checkMapWrite(buffer, arrayBuffer, size);
}).params(
pcombine([
poptions('size', [12, 512 * 1024]), //
pbool('mappable'),
])
);

g.test('createBufferMappedAsync', async t => {
const size = t.params.size;
const [buffer, arrayBuffer] = await t.device.createBufferMappedAsync({
size,
usage: GPUBufferUsage.COPY_SRC | (t.params.mappable ? GPUBufferUsage.MAP_WRITE : 0),
});
await t.checkMapWrite(buffer, arrayBuffer, size);
}).params(
pcombine([
poptions('size', [12, 512 * 1024]), //
pbool('mappable'),
])
);
65 changes: 65 additions & 0 deletions src/suites/cts/buffers/map.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
export const description = ``;

import { TestGroup, pbool, pcombine, poptions } from '../../../framework/index.js';

import { MappingTest } from './mapping_test.js';

export const g = new TestGroup(MappingTest);

g.test('mapWriteAsync', async t => {
const size = t.params.size;
const buffer = t.device.createBuffer({
size,
usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.MAP_WRITE,
});

const arrayBuffer = await buffer.mapWriteAsync();
await t.checkMapWrite(buffer, arrayBuffer, size);
}).params(poptions('size', [12, 512 * 1024]));

g.test('mapReadAsync', async t => {
const size = t.params.size;

const [buffer, init] = t.device.createBufferMapped({
size,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
});

const expected = new Uint32Array(new ArrayBuffer(size));
const data = new Uint32Array(init);
for (let i = 0; i < data.length; ++i) {
data[i] = expected[i] = i + 1;
}
buffer.unmap();

const actual = new Uint8Array(await buffer.mapReadAsync());
t.expectBuffer(actual, new Uint8Array(expected.buffer));
}).params(poptions('size', [12, 512 * 1024]));

g.test('createBufferMapped', async t => {
const size = t.params.size;
const [buffer, arrayBuffer] = t.device.createBufferMapped({
size,
usage: GPUBufferUsage.COPY_SRC | (t.params.mappable ? GPUBufferUsage.MAP_WRITE : 0),
});
await t.checkMapWrite(buffer, arrayBuffer, size);
}).params(
pcombine([
poptions('size', [12, 512 * 1024]), //
pbool('mappable'),
])
);

g.test('createBufferMappedAsync', async t => {
const size = t.params.size;
const [buffer, arrayBuffer] = await t.device.createBufferMappedAsync({
size,
usage: GPUBufferUsage.COPY_SRC | (t.params.mappable ? GPUBufferUsage.MAP_WRITE : 0),
});
await t.checkMapWrite(buffer, arrayBuffer, size);
}).params(
pcombine([
poptions('size', [12, 512 * 1024]), //
pbool('mappable'),
])
);
31 changes: 0 additions & 31 deletions src/suites/cts/buffers/mapWriteAsync.spec.ts

This file was deleted.

68 changes: 68 additions & 0 deletions src/suites/cts/buffers/map_detach.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
export const description = ``;

import { TestGroup, pbool, pcombine } from '../../../framework/index.js';
import { GPUTest } from '../gpu_test.js';

class F extends GPUTest {
checkDetach(buffer: GPUBuffer, arrayBuffer: ArrayBuffer, unmap: boolean, destroy: boolean): void {
const view = new Uint8Array(arrayBuffer);
this.expect(arrayBuffer.byteLength === 4);
this.expect(view.length === 4);

if (unmap) buffer.unmap();
if (destroy) buffer.destroy();

this.expect(arrayBuffer.byteLength === 0, 'ArrayBuffer should be detached');
this.expect(view.byteLength === 0, 'ArrayBufferView should be detached');
}
}

export const g = new TestGroup(F);

g.test('mapWriteAsync', async t => {
const buffer = t.device.createBuffer({ size: 4, usage: GPUBufferUsage.MAP_WRITE });
const arrayBuffer = await buffer.mapWriteAsync();
t.checkDetach(buffer, arrayBuffer, t.params.unmap, t.params.destroy);
}).params([
{ unmap: true, destroy: false }, //
{ unmap: false, destroy: true },
{ unmap: true, destroy: true },
]);

g.test('mapReadAsync', async t => {
const buffer = t.device.createBuffer({ size: 4, usage: GPUBufferUsage.MAP_READ });
const arrayBuffer = await buffer.mapReadAsync();
t.checkDetach(buffer, arrayBuffer, t.params.unmap, t.params.destroy);
}).params([
{ unmap: true, destroy: false }, //
{ unmap: false, destroy: true },
{ unmap: true, destroy: true },
]);

g.test('create mapped', async t => {
const desc = {
size: 4,
usage: GPUBufferUsage.MAP_WRITE,
};
const [buffer, arrayBuffer] = t.params.async
? await t.device.createBufferMappedAsync(desc)
: t.device.createBufferMapped(desc);

const view = new Uint8Array(arrayBuffer);
t.expect(arrayBuffer.byteLength === 4);
t.expect(view.length === 4);

if (t.params.unmap) buffer.unmap();
if (t.params.destroy) buffer.destroy();
t.expect(arrayBuffer.byteLength === 0, 'ArrayBuffer should be detached');
t.expect(view.byteLength === 0, 'ArrayBufferView should be detached');
}).params(
pcombine([
pbool('async'), //
[
{ unmap: true, destroy: false },
{ unmap: false, destroy: true },
{ unmap: true, destroy: true },
],
])
);
33 changes: 33 additions & 0 deletions src/suites/cts/buffers/map_oom.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export const description = ``;

import { TestGroup } from '../../../framework/index.js';
import { GPUTest } from '../gpu_test.js';

function getBufferDesc(): GPUBufferDescriptor {
return {
size: Number.MAX_SAFE_INTEGER,
usage: GPUBufferUsage.MAP_WRITE,
};
}

export const g = new TestGroup(GPUTest);

g.test('mapWriteAsync', async t => {
const buffer = t.device.createBuffer(getBufferDesc());
await t.shouldReject('RangeError', buffer.mapWriteAsync());
});

g.test('mapReadAsync', async t => {
const buffer = t.device.createBuffer(getBufferDesc());
await t.shouldReject('RangeError', buffer.mapReadAsync());
});

g.test('createBufferMapped', async t => {
await t.shouldThrow('RangeError', () => {
t.device.createBufferMapped(getBufferDesc());
});
});

g.test('createBufferAsync', async t => {
await t.shouldReject('RangeError', t.device.createBufferMappedAsync(getBufferDesc()));
});
33 changes: 33 additions & 0 deletions src/suites/cts/buffers/mapping_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { GPUTest } from '../gpu_test.js';

export class MappingTest extends GPUTest {
checkMapWrite(buffer: GPUBuffer, mappedContents: ArrayBuffer, size: number): Promise<void> {
this.checkMapWriteZeroed(mappedContents, size);

const mappedView = new Uint32Array(mappedContents);
const expected = new Uint32Array(new ArrayBuffer(size));
this.expect(mappedView.byteLength === size);
for (let i = 0; i < mappedView.length; ++i) {
mappedView[i] = expected[i] = i + 1;
}
buffer.unmap();

return this.expectContents(buffer, expected);
}

checkMapWriteZeroed(arrayBuffer: ArrayBuffer, expectedSize: number): void {
this.expect(arrayBuffer.byteLength === expectedSize);
const view = new Uint8Array(arrayBuffer);
this.expectZero(view);
}

expectZero(actual: Uint8Array): void {
const size = actual.byteLength;
for (let i = 0; i < size; ++i) {
if (actual[i] !== 0) {
this.fail(`at [${i}], expected zero, got ${actual[i]}`);
break;
}
}
}
}
2 changes: 1 addition & 1 deletion src/suites/cts/examples.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { GPUTest } from './gpu_test.js';
// - http://web-platform.test:8000/webgpu/cts.html?q=cts:examples:
//
// Tests here can be run individually or in groups:
// - http://localhost:8080/?runnow=1&q=cts:examples:basic/async:
// - http://localhost:8080/?runnow=1&q=cts:examples:basic/async=
// - http://localhost:8080/?runnow=1&q=cts:examples:basic/
// - http://localhost:8080/?runnow=1&q=cts:examples:

Expand Down
49 changes: 29 additions & 20 deletions src/suites/cts/gpu_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,36 @@ export class GPUTest extends Fixture {
this.queue.submit([c.finish()]);

const actual = new Uint8Array(await dst.mapReadAsync());
let failedPixels = 0;
for (let i = 0; i < size; ++i) {
if (actual[i] !== exp[i]) {
if (failedPixels > 4) {
this.rec.fail('... and more');
break;
}
failedPixels++;
this.rec.fail(`at [${i}], expected ${exp[i]}, got ${actual[i]}`);
this.expectBuffer(actual, exp);
});
}

expectBuffer(actual: Uint8Array, exp: Uint8Array): void {
const size = exp.byteLength;
if (actual.byteLength !== size) {
this.rec.fail('size mismatch');
return;
}
let failedPixels = 0;
for (let i = 0; i < size; ++i) {
if (actual[i] !== exp[i]) {
if (failedPixels > 4) {
this.rec.fail('... and more');
break;
}
failedPixels++;
this.rec.fail(`at [${i}], expected ${exp[i]}, got ${actual[i]}`);
}
if (size <= 256 && failedPixels > 0) {
const expHex = Array.from(exp)
.map(x => x.toString(16).padStart(2, '0'))
.join('');
const actHex = Array.from(actual)
.map(x => x.toString(16).padStart(2, '0'))
.join('');
this.rec.log('EXPECT: ' + expHex);
this.rec.log('ACTUAL: ' + actHex);
}
});
}
if (size <= 256 && failedPixels > 0) {
const expHex = Array.from(exp)
.map(x => x.toString(16).padStart(2, '0'))
.join('');
const actHex = Array.from(actual)
.map(x => x.toString(16).padStart(2, '0'))
.join('');
this.rec.log('EXPECT: ' + expHex);
this.rec.log('ACTUAL: ' + actHex);
}
}
}
8 changes: 6 additions & 2 deletions wpt/cts.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@
<textarea id=results></textarea>
<script type=module src="runtime/wpt.js"></script>

<meta name="variant" content="?q=cts:buffers/createBufferMapped:">
<meta name="variant" content="?q=cts:buffers/mapWriteAsync:">
<meta name="variant" content="?q=cts:buffers/create_mapped:">
<meta name="variant" content="?q=cts:buffers/map:">
<meta name="variant" content="?q=cts:buffers/map_detach:">
<meta name="variant" content="?q=cts:buffers/map_oom:">
<meta name="variant" content="?q=cts:canvas/context_creation:">
<meta name="variant" content="?q=cts:command_buffer/basic:">
<meta name="variant" content="?q=cts:command_buffer/copies:">
<meta name="variant" content="?q=cts:command_buffer/render/basic:">
<meta name="variant" content="?q=cts:fences:">

0 comments on commit 0206834

Please sign in to comment.