blob: fc8a472daf42e6e92b8d7d066cdbb678d603cd33 [file] [log] [blame]
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -07001export const description = `
2Examples of writing CTS tests with various features.
Kai Ninomiyacb13fba2019-10-24 16:59:36 -07003
4Start here when looking for examples of basic framework usage.
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -07005`;
6
Kai Ninomiyafe0cbfa2020-09-25 10:17:24 -07007import { pbool } from '../common/framework/params_builder.js';
Kai Ninomiya9cbb8002020-05-18 15:33:41 -07008import { makeTestGroup } from '../common/framework/test_group.js';
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -07009
10import { GPUTest } from './gpu_test.js';
11
12// To run these tests in the standalone runner, run `grunt build` or `grunt pre` then open:
Kai Ninomiya20bc11b2020-03-31 14:45:44 -070013// - http://localhost:8080/?runnow=1&q=webgpu:examples:
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070014// To run in WPT, copy/symlink the out-wpt/ directory as the webgpu/ directory in WPT, then open:
Kai Ninomiya20bc11b2020-03-31 14:45:44 -070015// - (wpt server url)/webgpu/cts.html?q=webgpu:examples:
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070016//
17// Tests here can be run individually or in groups:
Kai Ninomiya20bc11b2020-03-31 14:45:44 -070018// - ?q=webgpu:examples:basic/async=
19// - ?q=webgpu:examples:basic/
20// - ?q=webgpu:examples:
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070021
Kai Ninomiya9cbb8002020-05-18 15:33:41 -070022export const g = makeTestGroup(GPUTest);
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070023
Kai Ninomiya20bc11b2020-03-31 14:45:44 -070024// Note: spaces in test names are replaced with underscores: webgpu:examples:test_name=
Austin Eng639527e2020-04-14 16:20:36 -070025/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
Kai Ninomiya9cbb8002020-05-18 15:33:41 -070026g.test('test_name').fn(t => {});
Kai Ninomiya04ec6b62019-10-25 00:35:32 -070027
Kai Ninomiyafb584a52020-04-16 16:43:24 -070028g.test('basic').fn(t => {
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070029 t.expect(true);
30 t.expect(true, 'true should be true');
31
32 t.shouldThrow(
Kai Ninomiyabb2e71f2019-08-02 16:25:56 -070033 // The expected '.name' of the thrown error.
34 'TypeError',
35 // This function is run inline inside shouldThrow, and is expected to throw.
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070036 () => {
Kai Ninomiyabb2e71f2019-08-02 16:25:56 -070037 throw new TypeError();
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070038 },
Kai Ninomiyabb2e71f2019-08-02 16:25:56 -070039 // Log message.
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070040 'function should throw Error'
41 );
42});
43
Kai Ninomiya9cbb8002020-05-18 15:33:41 -070044g.test('basic,async').fn(async t => {
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070045 // shouldReject must be awaited to ensure it can wait for the promise before the test ends.
Kai Ninomiyac42e2982019-10-23 15:44:28 -070046 t.shouldReject(
Kai Ninomiyabb2e71f2019-08-02 16:25:56 -070047 // The expected '.name' of the thrown error.
48 'TypeError',
49 // Promise expected to reject.
50 Promise.reject(new TypeError()),
51 // Log message.
52 'Promise.reject should reject'
53 );
54
55 // Promise can also be an IIFE.
Kai Ninomiyac42e2982019-10-23 15:44:28 -070056 t.shouldReject(
Kai Ninomiyabb2e71f2019-08-02 16:25:56 -070057 'TypeError',
58 (async () => {
59 throw new TypeError();
60 })(),
61 'Promise.reject should reject'
62 );
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070063});
64
Kai Ninomiya13820262019-10-17 15:30:56 -070065// A test can be parameterized with a simple array of objects.
66//
67// Parameters can be public (x, y) which means they're part of the case name.
68// They can also be private by starting with an underscore (_result), which passes
69// them into the test but does not make them part of the case name:
70//
Kai Ninomiya20bc11b2020-03-31 14:45:44 -070071// - webgpu:examples:basic/params={"x":2,"y":4} runs with t.params = {x: 2, y: 5, _result: 6}.
72// - webgpu:examples:basic/params={"x":-10,"y":18} runs with t.params = {x: -10, y: 18, _result: 8}.
Kai Ninomiya9cbb8002020-05-18 15:33:41 -070073g.test('basic,params')
Kai Ninomiyafb584a52020-04-16 16:43:24 -070074 .params([
75 { x: 2, y: 4, _result: 6 }, //
76 { x: -10, y: 18, _result: 8 },
77 ])
78 .fn(t => {
79 t.expect(t.params.x + t.params.y === t.params._result);
80 });
Kai Ninomiya13820262019-10-17 15:30:56 -070081// (note the blank comment above to enforce newlines on autoformat)
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070082
Kai Ninomiya9cbb8002020-05-18 15:33:41 -070083g.test('gpu,async').fn(async t => {
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070084 const fence = t.queue.createFence();
85 t.queue.signal(fence, 2);
86 await fence.onCompletion(1);
87 t.expect(fence.getCompletedValue() === 2);
88});
89
Kai Ninomiya9cbb8002020-05-18 15:33:41 -070090g.test('gpu,buffers').fn(async t => {
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070091 const data = new Uint32Array([0, 1234, 0]);
Kai Ninomiyabe420af2020-07-24 18:32:40 -070092 const src = t.device.createBuffer({
93 mappedAtCreation: true,
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070094 size: 12,
95 usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
96 });
Kai Ninomiyabe420af2020-07-24 18:32:40 -070097 new Uint32Array(src.getMappedRange()).set(data);
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -070098 src.unmap();
99
100 // Use the expectContents helper to check the actual contents of a GPUBuffer.
101 // Like shouldReject, it must be awaited.
Kai Ninomiyac42e2982019-10-23 15:44:28 -0700102 t.expectContents(src, data);
Kai Ninomiya8e4e5dd2019-08-02 14:00:30 -0700103});
Kai Ninomiyafe0cbfa2020-09-25 10:17:24 -0700104
105// One of the following two tests should be skipped on most platforms.
106
107g.test('gpu,with_texture_compression,bc')
108 .params(pbool('textureCompressionBC'))
109 .fn(async t => {
110 const { textureCompressionBC } = t.params;
111
112 if (textureCompressionBC) {
Kai Ninomiya001316a2020-09-29 09:47:08 -0700113 await t.selectDeviceOrSkipTestCase({ extensions: ['texture-compression-bc'] });
Kai Ninomiyafe0cbfa2020-09-25 10:17:24 -0700114 }
115
116 const shouldError = !textureCompressionBC;
117 t.expectGPUError(
118 'validation',
119 () => {
120 t.device.createTexture({
121 format: 'bc1-rgba-unorm',
122 size: [4, 4, 1],
123 usage: GPUTextureUsage.SAMPLED,
124 });
125 },
126 shouldError
127 );
128 });
129
130g.test('gpu,with_texture_compression,etc')
131 .params(pbool('textureCompressionETC'))
132 .fn(async t => {
133 const { textureCompressionETC } = t.params;
134
135 if (textureCompressionETC) {
Kai Ninomiya001316a2020-09-29 09:47:08 -0700136 await t.selectDeviceOrSkipTestCase({
Kai Ninomiyafe0cbfa2020-09-25 10:17:24 -0700137 extensions: ['texture-compression-etc' as GPUExtensionName],
138 });
139 }
140
141 t.device;
142 // TODO: Should actually test createTexture with an ETC format here.
143 });