summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/api/operation/device/lost.spec.ts
diff options
context:
space:
mode:
Diffstat (limited to 'dom/webgpu/tests/cts/checkout/src/webgpu/api/operation/device/lost.spec.ts')
-rw-r--r--dom/webgpu/tests/cts/checkout/src/webgpu/api/operation/device/lost.spec.ts92
1 files changed, 92 insertions, 0 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/webgpu/api/operation/device/lost.spec.ts b/dom/webgpu/tests/cts/checkout/src/webgpu/api/operation/device/lost.spec.ts
new file mode 100644
index 0000000000..88d08b77f5
--- /dev/null
+++ b/dom/webgpu/tests/cts/checkout/src/webgpu/api/operation/device/lost.spec.ts
@@ -0,0 +1,92 @@
+export const description = `
+Tests for GPUDevice.lost.
+`;
+
+import { Fixture } from '../../../../common/framework/fixture.js';
+import { makeTestGroup } from '../../../../common/framework/test_group.js';
+import { attemptGarbageCollection } from '../../../../common/util/collect_garbage.js';
+import { getGPU } from '../../../../common/util/navigator_gpu.js';
+import {
+ assert,
+ assertNotSettledWithinTime,
+ raceWithRejectOnTimeout,
+} from '../../../../common/util/util.js';
+
+class DeviceLostTests extends Fixture {
+ // Default timeout for waiting for device lost is 2 seconds.
+ readonly kDeviceLostTimeoutMS = 2000;
+
+ getDeviceLostWithTimeout(lost: Promise<GPUDeviceLostInfo>): Promise<GPUDeviceLostInfo> {
+ return raceWithRejectOnTimeout(lost, this.kDeviceLostTimeoutMS, 'device was not lost');
+ }
+
+ expectDeviceDestroyed(device: GPUDevice): void {
+ this.eventualAsyncExpectation(async niceStack => {
+ try {
+ const lost = await this.getDeviceLostWithTimeout(device.lost);
+ this.expect(lost.reason === 'destroyed', 'device was lost from destroy');
+ } catch (ex) {
+ niceStack.message = 'device was not lost';
+ this.rec.expectationFailed(niceStack);
+ }
+ });
+ }
+}
+
+export const g = makeTestGroup(DeviceLostTests);
+
+g.test('not_lost_on_gc')
+ .desc(
+ `'lost' is never resolved by GPUDevice being garbage collected (with attemptGarbageCollection).`
+ )
+ .fn(async t => {
+ // Wraps a lost promise object creation in a function scope so that the device has the best
+ // chance of being gone and ready for GC before trying to resolve the lost promise.
+ const { lost } = await (async () => {
+ const adapter = await getGPU().requestAdapter();
+ assert(adapter !== null);
+ const lost = (await adapter.requestDevice()).lost;
+ return { lost };
+ })();
+ await assertNotSettledWithinTime(lost, t.kDeviceLostTimeoutMS, 'device was unexpectedly lost');
+
+ await attemptGarbageCollection();
+ });
+
+g.test('lost_on_destroy')
+ .desc(`'lost' is resolved, with reason='destroyed', on GPUDevice.destroy().`)
+ .fn(async t => {
+ const adapter = await getGPU().requestAdapter();
+ assert(adapter !== null);
+ const device: GPUDevice = await adapter.requestDevice();
+ t.expectDeviceDestroyed(device);
+ device.destroy();
+ });
+
+g.test('same_object')
+ .desc(`'lost' provides the same Promise and GPUDeviceLostInfo objects each time it's accessed.`)
+ .fn(async t => {
+ const adapter = await getGPU().requestAdapter();
+ assert(adapter !== null);
+ const device: GPUDevice = await adapter.requestDevice();
+
+ // The promises should be the same promise object.
+ const lostPromise1 = device.lost;
+ const lostPromise2 = device.lost;
+ t.expect(lostPromise1 === lostPromise2);
+
+ // Promise object should still be the same after destroy.
+ device.destroy();
+ const lostPromise3 = device.lost;
+ t.expect(lostPromise1 === lostPromise3);
+
+ // The results should also be the same result object.
+ const lost1 = await t.getDeviceLostWithTimeout(lostPromise1);
+ const lost2 = await t.getDeviceLostWithTimeout(lostPromise2);
+ const lost3 = await t.getDeviceLostWithTimeout(lostPromise3);
+ // Promise object should still be the same after we've been notified about device loss.
+ const lostPromise4 = device.lost;
+ t.expect(lostPromise1 === lostPromise4);
+ const lost4 = await t.getDeviceLostWithTimeout(lostPromise4);
+ t.expect(lost1 === lost2 && lost2 === lost3 && lost3 === lost4);
+ });