blob: 3f69e560828d95e2af15ef37b33c9033ec54e6dc [file] [log] [blame]
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script>
async function testFunction(t) {
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const queue = device.getQueue();
{
// Test default initial value.
const fence = queue.createFence({});
assert_equals(fence.getCompletedValue(), 0);
}
{
// Test initial value.
const fence = queue.createFence({ initialValue: 2 });
assert_equals(fence.getCompletedValue(), 2);
}
{
// Promise resolves when onCompletion value is less than signal value.
const fence = queue.createFence({});
queue.signal(fence, 2);
await fence.onCompletion(1);
assert_equals(fence.getCompletedValue(), 2);
}
{
// Promise resolves when onCompletion value is equal to signal value.
const fence = queue.createFence({});
queue.signal(fence, 2);
await fence.onCompletion(2);
assert_equals(fence.getCompletedValue(), 2);
}
{
// Promise resolves when signal is called multiple times.
const fence = queue.createFence({});
queue.signal(fence, 1);
queue.signal(fence, 2);
await fence.onCompletion(2);
assert_equals(fence.getCompletedValue(), 2);
}
{
// Promise resolves if fence has already completed.
const fence = queue.createFence({});
queue.signal(fence, 2);
// Wait for value to update.
while (fence.getCompletedValue() < 2) {
await new Promise(resolve => {
setTimeout(resolve, 10);
});
}
assert_equals(fence.getCompletedValue(), 2);
await fence.onCompletion(2);
assert_equals(fence.getCompletedValue(), 2);
}
{
// Test dropping references to the fence and onCompletion promise does not
// crash.
{
const fence = queue.createFence({});
queue.signal(fence, 2);
fence.onCompletion(2);
}
window.gc();
}
{
// Test dropping references to the fence and holding the promise does not
// crash.
let promise;
{
const fence = queue.createFence({});
queue.signal(fence, 2);
promise = fence.onCompletion(2);
}
window.gc();
await promise;
}
{
// Test many calls to signal and wait on fence values one at a time.
const fence = queue.createFence({});
for (let i = 1; i <= 20; ++i) {
queue.signal(fence, i);
await fence.onCompletion(i);
assert_equals(fence.getCompletedValue(), i);
}
}
{
// Test many calls to signal and wait on all fence values.
const fence = queue.createFence({});
const promises = [];
for (let i = 1; i <= 20; ++i) {
queue.signal(fence, i);
promises.push(fence.onCompletion(i).then(() => {
assert_true(fence.getCompletedValue() >= i);
}));
}
await Promise.all(promises);
assert_equals(fence.getCompletedValue(), 20);
}
{
// Test it is illegal to wait on a fence without signaling the value.
const fence = queue.createFence({});
const promise = fence.onCompletion(2);
await promise_rejects(
t, 'OperationError', promise, "Wait on fence without signal");
}
{
// Test it is illegal to wait on a fence before it is signaled.
const fence = queue.createFence({});
const promise = fence.onCompletion(2);
queue.signal(fence, 2);
await promise_rejects(
t, 'OperationError', promise, "Wait on fence before signal");
}
{
// Test it is illegal to wait on a value greater than the signaled value.
const fence = queue.createFence({});
queue.signal(fence, 2);
const promise = fence.onCompletion(3);
await promise_rejects(
t, 'OperationError', promise, "Wait on value greater than signaled value");
}
}
promise_test(t => testFunction(t), "Test WebGPU fences");
</script>