Update WebGPU CTS (#30954)

* Update WebGPU CTS to ae15a59832

* Add internal to GPUErrorFilter to make more test work

* No crash in CreateRenderBundleEncoder

* getCompilationInfo

* Update expectations
This commit is contained in:
Samson 2023-12-28 18:32:21 +01:00 committed by GitHub
parent 90a25ab2e1
commit e79171ec01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
822 changed files with 135542 additions and 329305 deletions

View file

@ -1054,10 +1054,12 @@ impl GPUDeviceMethods for GPUDevice {
.map(|f| Some(convert_texture_format(*f))) .map(|f| Some(convert_texture_format(*f)))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
), ),
depth_stencil: Some(wgt::RenderBundleDepthStencil { depth_stencil: descriptor.parent.depthStencilFormat.map(|dsf| {
format: convert_texture_format(descriptor.parent.depthStencilFormat.unwrap()), wgt::RenderBundleDepthStencil {
depth_read_only: descriptor.depthReadOnly, format: convert_texture_format(dsf),
stencil_read_only: descriptor.stencilReadOnly, depth_read_only: descriptor.depthReadOnly,
stencil_read_only: descriptor.stencilReadOnly,
}
}), }),
sample_count: descriptor.parent.sampleCount, sample_count: descriptor.parent.sampleCount,
multiview: None, multiview: None,

View file

@ -63,7 +63,7 @@ impl GPUShaderModuleMethods for GPUShaderModule {
} }
/// https://gpuweb.github.io/gpuweb/#dom-gpushadermodule-getcompilationinfo /// https://gpuweb.github.io/gpuweb/#dom-gpushadermodule-getcompilationinfo
fn CompilationInfo(&self) -> Fallible<Rc<Promise>> { fn GetCompilationInfo(&self) -> Fallible<Rc<Promise>> {
todo!() todo!("Missing in wgpu: https://github.com/gfx-rs/wgpu/issues/2170")
} }
} }

View file

@ -487,7 +487,7 @@ dictionary GPUPipelineLayoutDescriptor : GPUObjectDescriptorBase {
[Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"] [Exposed=(Window, DedicatedWorker), Serializable, Pref="dom.webgpu.enabled"]
interface GPUShaderModule { interface GPUShaderModule {
[Throws] [Throws]
Promise<GPUCompilationInfo> compilationInfo(); Promise<GPUCompilationInfo> getCompilationInfo();
}; };
GPUShaderModule includes GPUObjectBase; GPUShaderModule includes GPUObjectBase;
@ -1101,8 +1101,9 @@ interface GPUOutOfMemoryError {
typedef (GPUOutOfMemoryError or GPUValidationError) GPUError; typedef (GPUOutOfMemoryError or GPUValidationError) GPUError;
enum GPUErrorFilter { enum GPUErrorFilter {
"validation",
"out-of-memory", "out-of-memory",
"validation" "internal",
}; };
partial interface GPUDevice { partial interface GPUDevice {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,2 +0,0 @@
[canvas_composite_alpha_bgra8unorm_opaque_copy.https.html]
expected: [PASS, FAIL]

View file

@ -1,2 +1,2 @@
[canvas_composite_alpha_bgra8unorm_opaque_draw.https.html] [canvas_composite_alpha_bgra8unorm_opaque_draw.https.html]
expected: [PASS, FAIL] expected: [PASS, FAIL, CRASH]

View file

@ -1,2 +0,0 @@
[canvas_composite_alpha_rgba8unorm_opaque_copy.https.html]
expected: [PASS, FAIL]

View file

@ -1,2 +0,0 @@
[canvas_composite_alpha_rgba8unorm_opaque_draw.https.html]
expected: [PASS, FAIL]

View file

@ -1,2 +1,2 @@
[canvas_composite_alpha_rgba8unorm_premultiplied_draw.https.html] [canvas_composite_alpha_rgba8unorm_premultiplied_draw.https.html]
expected: FAIL expected: [CRASH, FAIL]

View file

@ -1 +1 @@
f2b59e03621238d0d0fd6305be2c406ce3e45ac2 ae15a59832989c22982acaeaccdf5d379afced62

View file

@ -1,9 +1,66 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ **/ /**
* Utilities to improve the performance of the CTS, by caching data that is
* expensive to build using a two-level cache (in-memory, pre-computed file).
*/import { assert } from '../util/util.js';
/** DataCache is an interface to a data store used to hold cached data */
/** Logger is a basic debug logger function */
/**
* DataCacheNode represents a single cache entry in the LRU DataCache.
* DataCacheNode is a doubly linked list, so that least-recently-used entries can be removed, and
* cache hits can move the node to the front of the list.
*/
class DataCacheNode {
constructor(path, data) {
this.path = path;
this.data = data;
}
/** insertAfter() re-inserts this node in the doubly-linked list after `prev` */
insertAfter(prev) {
this.unlink();
this.next = prev.next;
this.prev = prev;
prev.next = this;
if (this.next) {
this.next.prev = this;
}
}
/** unlink() removes this node from the doubly-linked list */
unlink() {
const prev = this.prev;
const next = this.next;
if (prev) {
prev.next = next;
}
if (next) {
next.prev = prev;
}
this.prev = null;
this.next = null;
}
// The file path this node represents
// The deserialized data for this node
prev = null; // The previous node in the doubly-linked list
next = null; // The next node in the doubly-linked list
}
/** DataCache is an interface to a LRU-cached data store used to hold data cached by path */
export class DataCache { export class DataCache {
constructor() {
this.lruHeadNode.next = this.lruTailNode;
this.lruTailNode.prev = this.lruHeadNode;
}
/** setDataStore() sets the backing data store used by the data cache */ /** setDataStore() sets the backing data store used by the data cache */
setStore(dataStore) { setStore(dataStore) {
this.dataStore = dataStore; this.dataStore = dataStore;
@ -20,11 +77,14 @@ export class DataCache {
* building the data and storing it in the cache. * building the data and storing it in the cache.
*/ */
async fetch(cacheable) { async fetch(cacheable) {
// First check the in-memory cache {
let data = this.cache.get(cacheable.path); // First check the in-memory cache
if (data !== undefined) { const node = this.cache.get(cacheable.path);
this.log('in-memory cache hit'); if (node !== undefined) {
return Promise.resolve(data); this.log('in-memory cache hit');
node.insertAfter(this.lruHeadNode);
return Promise.resolve(node.data);
}
} }
this.log('in-memory cache miss'); this.log('in-memory cache miss');
// In in-memory cache miss. // In in-memory cache miss.
@ -41,25 +101,51 @@ export class DataCache {
} }
if (serialized !== undefined) { if (serialized !== undefined) {
this.log(`deserializing`); this.log(`deserializing`);
data = cacheable.deserialize(serialized); const data = cacheable.deserialize(serialized);
this.cache.set(cacheable.path, data); this.addToCache(cacheable.path, data);
return data; return data;
} }
} }
// Not found anywhere. Build the data, and cache for future lookup. // Not found anywhere. Build the data, and cache for future lookup.
this.log(`cache: building (${cacheable.path})`); this.log(`cache: building (${cacheable.path})`);
data = await cacheable.build(); const data = await cacheable.build();
this.cache.set(cacheable.path, data); this.addToCache(cacheable.path, data);
return data; return data;
} }
/**
* addToCache() creates a new node for `path` and `data`, inserting the new node at the front of
* the doubly-linked list. If the number of entries in the cache exceeds this.maxCount, then the
* least recently used entry is evicted
* @param path the file path for the data
* @param data the deserialized data
*/
addToCache(path, data) {
if (this.cache.size >= this.maxCount) {
const toEvict = this.lruTailNode.prev;
assert(toEvict !== null);
toEvict.unlink();
this.cache.delete(toEvict.path);
this.log(`evicting ${toEvict.path}`);
}
const node = new DataCacheNode(path, data);
node.insertAfter(this.lruHeadNode);
this.cache.set(path, node);
this.log(`added ${path}. new count: ${this.cache.size}`);
}
log(msg) { log(msg) {
if (this.debugLogger !== null) { if (this.debugLogger !== null) {
this.debugLogger(`DataCache: ${msg}`); this.debugLogger(`DataCache: ${msg}`);
} }
} }
// Max number of entries in the cache before LRU entries are evicted.
maxCount = 4;
cache = new Map(); cache = new Map();
lruHeadNode = new DataCacheNode('', null); // placeholder node (no path or data)
lruTailNode = new DataCacheNode('', null); // placeholder node (no path or data)
unavailableFiles = new Set(); unavailableFiles = new Set();
dataStore = null; dataStore = null;
debugLogger = null; debugLogger = null;

View file

@ -1,6 +1,6 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { assert, unreachable } from '../util/util.js'; **/import { assert, unreachable } from '../util/util.js';
export class SkipTestCase extends Error {} export class SkipTestCase extends Error {}
export class UnexpectedPassError extends Error {} export class UnexpectedPassError extends Error {}
@ -9,15 +9,20 @@ export { TestCaseRecorder } from '../internal/logging/test_case_recorder.js';
/** The fully-general type for params passed to a test function invocation. */ /** The fully-general type for params passed to a test function invocation. */
export class SubcaseBatchState { export class SubcaseBatchState {
constructor( constructor(
recorder, recorder,
/** The case parameters for this test fixture shared state. Subcase params are not included. */ /** The case parameters for this test fixture shared state. Subcase params are not included. */
params params)
) { {this.recorder = recorder;this.params = params;}
this.recorder = recorder;
this.params = params;
}
/** /**
* Runs before the `.before()` function. * Runs before the `.before()` function.
@ -42,6 +47,8 @@ export class SubcaseBatchState {
* (i.e. every time the test function is run). * (i.e. every time the test function is run).
*/ */
export class Fixture { export class Fixture {
/** /**
* Interface for recording logs and test status. * Interface for recording logs and test status.
* *
@ -138,11 +145,11 @@ export class Fixture {
tryTrackForCleanup(o) { tryTrackForCleanup(o) {
if (typeof o === 'object' && o !== null) { if (typeof o === 'object' && o !== null) {
if ( if (
'destroy' in o || 'destroy' in o ||
'close' in o || 'close' in o ||
o instanceof WebGLRenderingContext || o instanceof WebGLRenderingContext ||
o instanceof WebGL2RenderingContext o instanceof WebGL2RenderingContext)
) { {
this.objectsToCleanUp.push(o); this.objectsToCleanUp.push(o);
} }
} }
@ -214,7 +221,7 @@ export class Fixture {
/** Expect that the provided promise resolves (fulfills). */ /** Expect that the provided promise resolves (fulfills). */
shouldResolve(p, msg) { shouldResolve(p, msg) {
this.eventualAsyncExpectation(async niceStack => { this.eventualAsyncExpectation(async (niceStack) => {
const m = msg ? ': ' + msg : ''; const m = msg ? ': ' + msg : '';
try { try {
await p; await p;
@ -230,16 +237,26 @@ export class Fixture {
} }
/** Expect that the provided promise rejects, with the provided exception name. */ /** Expect that the provided promise rejects, with the provided exception name. */
shouldReject(expectedName, p, msg) { shouldReject(
this.eventualAsyncExpectation(async niceStack => { expectedName,
const m = msg ? ': ' + msg : ''; p,
{ allowMissingStack = false, message } = {})
{
this.eventualAsyncExpectation(async (niceStack) => {
const m = message ? ': ' + message : '';
try { try {
await p; await p;
niceStack.message = 'DID NOT REJECT' + m; niceStack.message = 'DID NOT REJECT' + m;
this.rec.expectationFailed(niceStack); this.rec.expectationFailed(niceStack);
} catch (ex) { } catch (ex) {
niceStack.message = 'rejected as expected' + m;
this.expectErrorValue(expectedName, ex, niceStack); this.expectErrorValue(expectedName, ex, niceStack);
if (!allowMissingStack) {
if (!(ex instanceof Error && typeof ex.stack === 'string')) {
const exMessage = ex instanceof Error ? ex.message : '?';
niceStack.message = `rejected as expected, but missing stack (${exMessage})${m}`;
this.rec.expectationFailed(niceStack);
}
}
} }
}); });
} }
@ -250,8 +267,12 @@ export class Fixture {
* *
* MAINTENANCE_TODO: Change to `string | false` so the exception name is always checked. * MAINTENANCE_TODO: Change to `string | false` so the exception name is always checked.
*/ */
shouldThrow(expectedError, fn, msg) { shouldThrow(
const m = msg ? ': ' + msg : ''; expectedError,
fn,
{ allowMissingStack = false, message } = {})
{
const m = message ? ': ' + message : '';
try { try {
fn(); fn();
if (expectedError === false) { if (expectedError === false) {
@ -264,6 +285,11 @@ export class Fixture {
this.rec.expectationFailed(new Error('threw unexpectedly' + m)); this.rec.expectationFailed(new Error('threw unexpectedly' + m));
} else { } else {
this.expectErrorValue(expectedError, ex, new Error(m)); this.expectErrorValue(expectedError, ex, new Error(m));
if (!allowMissingStack) {
if (!(ex instanceof Error && typeof ex.stack === 'string')) {
this.rec.expectationFailed(new Error('threw as expected, but missing stack' + m));
}
}
} }
} }
} }
@ -283,8 +309,11 @@ export class Fixture {
* If the argument is an `Error`, fail (or warn). If it's `undefined`, no-op. * If the argument is an `Error`, fail (or warn). If it's `undefined`, no-op.
* If the argument is an array, apply the above behavior on each of elements. * If the argument is an array, apply the above behavior on each of elements.
*/ */
expectOK(error, { mode = 'fail', niceStack } = {}) { expectOK(
const handleError = error => { error,
{ mode = 'fail', niceStack } = {})
{
const handleError = (error) => {
if (error instanceof Error) { if (error instanceof Error) {
if (niceStack) { if (niceStack) {
error.stack = niceStack.stack; error.stack = niceStack.stack;
@ -308,9 +337,22 @@ export class Fixture {
} }
} }
eventualExpectOK(error, { mode = 'fail' } = {}) { eventualExpectOK(
this.eventualAsyncExpectation(async niceStack => { error,
{ mode = 'fail' } = {})
{
this.eventualAsyncExpectation(async (niceStack) => {
this.expectOK(await error, { mode, niceStack }); this.expectOK(await error, { mode, niceStack });
}); });
} }
} }
/**
* FixtureClass encapsulates a constructor for fixture and a corresponding
* shared state factory function. An interface version of the type is also
* defined for mixin declaration use ONLY. The interface version is necessary
* because mixin classes need a constructor with a single any[] rest
* parameter.
*/

View file

@ -1,6 +1,18 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { assert } from '../util/util.js'; /** Metadata about tests (that can't be derived at runtime). */ **/import { assert } from '../util/util.js'; /** Metadata about tests (that can't be derived at runtime). */
export function loadMetadataForSuite(suiteDir) { export function loadMetadataForSuite(suiteDir) {
assert(typeof require !== 'undefined', 'loadMetadataForSuite is only implemented on Node'); assert(typeof require !== 'undefined', 'loadMetadataForSuite is only implemented on Node');

View file

@ -1,14 +1,113 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { mergeParams, mergeParamsChecked } from '../internal/params_utils.js'; **/import { mergeParams, mergeParamsChecked } from '../internal/params_utils.js';import { comparePublicParamsPaths, Ordering } from '../internal/query/compare.js';import { stringifyPublicParams } from '../internal/query/stringify_params.js';
import { comparePublicParamsPaths, Ordering } from '../internal/query/compare.js';
import { stringifyPublicParams } from '../internal/query/stringify_params.js';
import { assert, mapLazy, objectEquals } from '../util/util.js'; import { assert, mapLazy, objectEquals } from '../util/util.js';
// ================================================================
// "Public" ParamsBuilder API / Documentation
// ================================================================
/**
* Provides doc comments for the methods of CaseParamsBuilder and SubcaseParamsBuilder.
* (Also enforces rough interface match between them.)
*/
/**
* Determines the resulting parameter object type which would be generated by an object of
* the given ParamsBuilder type.
*/
// ================================================================
// Implementation
// ================================================================
/**
* Iterable over pairs of either:
* - `[case params, Iterable<subcase params>]` if there are subcases.
* - `[case params, undefined]` if not.
*/
/** /**
* Base class for `CaseParamsBuilder` and `SubcaseParamsBuilder`. * Base class for `CaseParamsBuilder` and `SubcaseParamsBuilder`.
*/ */
export class ParamsBuilderBase { export class ParamsBuilderBase {
constructor(cases) { constructor(cases) {
this.cases = cases; this.cases = cases;
} }
@ -16,12 +115,22 @@ export class ParamsBuilderBase {
/** /**
* Hidden from test files. Use `builderIterateCasesWithSubcases` to access this. * Hidden from test files. Use `builderIterateCasesWithSubcases` to access this.
*/ */
} }
/** /**
* Calls the (normally hidden) `iterateCasesWithSubcases()` method. * Calls the (normally hidden) `iterateCasesWithSubcases()` method.
*/ */
export function builderIterateCasesWithSubcases(builder, caseFilter) { export function builderIterateCasesWithSubcases(
builder,
caseFilter)
{
return builder.iterateCasesWithSubcases(caseFilter); return builder.iterateCasesWithSubcases(caseFilter);
} }
@ -33,7 +142,10 @@ export function builderIterateCasesWithSubcases(builder, caseFilter) {
* *
* This means, for example, that the `unit` passed into `TestBuilder.params()` can be reused. * This means, for example, that the `unit` passed into `TestBuilder.params()` can be reused.
*/ */
export class CaseParamsBuilder extends ParamsBuilderBase { export class CaseParamsBuilder extends
ParamsBuilderBase
{
*iterateCasesWithSubcases(caseFilter) { *iterateCasesWithSubcases(caseFilter) {
for (const caseP of this.cases(caseFilter)) { for (const caseP of this.cases(caseFilter)) {
if (caseFilter) { if (caseFilter) {
@ -54,7 +166,9 @@ export class CaseParamsBuilder extends ParamsBuilderBase {
} }
/** @inheritDoc */ /** @inheritDoc */
expandWithParams(expander) { expandWithParams(
expander)
{
const baseGenerator = this.cases; const baseGenerator = this.cases;
return new CaseParamsBuilder(function* (caseFilter) { return new CaseParamsBuilder(function* (caseFilter) {
for (const a of baseGenerator(caseFilter)) { for (const a of baseGenerator(caseFilter)) {
@ -74,7 +188,10 @@ export class CaseParamsBuilder extends ParamsBuilderBase {
} }
/** @inheritDoc */ /** @inheritDoc */
expand(key, expander) { expand(
key,
expander)
{
const baseGenerator = this.cases; const baseGenerator = this.cases;
return new CaseParamsBuilder(function* (caseFilter) { return new CaseParamsBuilder(function* (caseFilter) {
for (const a of baseGenerator(caseFilter)) { for (const a of baseGenerator(caseFilter)) {
@ -94,7 +211,9 @@ export class CaseParamsBuilder extends ParamsBuilderBase {
} }
/** @inheritDoc */ /** @inheritDoc */
combineWithParams(newParams) { combineWithParams(
newParams)
{
assertNotGenerator(newParams); assertNotGenerator(newParams);
const seenValues = new Set(); const seenValues = new Set();
for (const params of newParams) { for (const params of newParams) {
@ -107,9 +226,12 @@ export class CaseParamsBuilder extends ParamsBuilderBase {
} }
/** @inheritDoc */ /** @inheritDoc */
combine(key, values) { combine(
key,
values)
{
assertNotGenerator(values); assertNotGenerator(values);
const mapped = mapLazy(values, v => ({ [key]: v })); const mapped = mapLazy(values, (v) => ({ [key]: v }));
return this.combineWithParams(mapped); return this.combineWithParams(mapped);
} }
@ -125,7 +247,7 @@ export class CaseParamsBuilder extends ParamsBuilderBase {
/** @inheritDoc */ /** @inheritDoc */
unless(pred) { unless(pred) {
return this.filter(x => !pred(x)); return this.filter((x) => !pred(x));
} }
/** /**
@ -156,8 +278,16 @@ export const kUnitCaseParamsBuilder = new CaseParamsBuilder(function* () {
* SubcaseParamsBuilder is immutable. Each method call returns a new, immutable object, * SubcaseParamsBuilder is immutable. Each method call returns a new, immutable object,
* modifying the list of subcases according to the method called. * modifying the list of subcases according to the method called.
*/ */
export class SubcaseParamsBuilder extends ParamsBuilderBase { export class SubcaseParamsBuilder extends
constructor(cases, generator) { ParamsBuilderBase
{
constructor(
cases,
generator)
{
super(cases); super(cases);
this.subcases = generator; this.subcases = generator;
} }
@ -175,13 +305,18 @@ export class SubcaseParamsBuilder extends ParamsBuilderBase {
const subcases = Array.from(this.subcases(caseP)); const subcases = Array.from(this.subcases(caseP));
if (subcases.length) { if (subcases.length) {
yield [caseP, subcases]; yield [
caseP,
subcases];
} }
} }
} }
/** @inheritDoc */ /** @inheritDoc */
expandWithParams(expander) { expandWithParams(
expander)
{
const baseGenerator = this.subcases; const baseGenerator = this.subcases;
return new SubcaseParamsBuilder(this.cases, function* (base) { return new SubcaseParamsBuilder(this.cases, function* (base) {
for (const a of baseGenerator(base)) { for (const a of baseGenerator(base)) {
@ -193,7 +328,10 @@ export class SubcaseParamsBuilder extends ParamsBuilderBase {
} }
/** @inheritDoc */ /** @inheritDoc */
expand(key, expander) { expand(
key,
expander)
{
const baseGenerator = this.subcases; const baseGenerator = this.subcases;
return new SubcaseParamsBuilder(this.cases, function* (base) { return new SubcaseParamsBuilder(this.cases, function* (base) {
for (const a of baseGenerator(base)) { for (const a of baseGenerator(base)) {
@ -208,13 +346,18 @@ export class SubcaseParamsBuilder extends ParamsBuilderBase {
} }
/** @inheritDoc */ /** @inheritDoc */
combineWithParams(newParams) { combineWithParams(
newParams)
{
assertNotGenerator(newParams); assertNotGenerator(newParams);
return this.expandWithParams(() => newParams); return this.expandWithParams(() => newParams);
} }
/** @inheritDoc */ /** @inheritDoc */
combine(key, values) { combine(
key,
values)
{
assertNotGenerator(values); assertNotGenerator(values);
return this.expand(key, () => values); return this.expand(key, () => values);
} }
@ -231,7 +374,7 @@ export class SubcaseParamsBuilder extends ParamsBuilderBase {
/** @inheritDoc */ /** @inheritDoc */
unless(pred) { unless(pred) {
return this.filter(x => !pred(x)); return this.filter((x) => !pred(x));
} }
} }
@ -239,7 +382,7 @@ export class SubcaseParamsBuilder extends ParamsBuilderBase {
function assertNotGenerator(x) { function assertNotGenerator(x) {
if ('constructor' in x) { if ('constructor' in x) {
assert( assert(
x.constructor !== (function* () {})().constructor, x.constructor !== function* () {}().constructor,
'Argument must not be a generator, as generators are not reusable' 'Argument must not be a generator, as generators are not reusable'
); );
} }

View file

@ -1,11 +1,10 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ /** **/ /**
* Base path for resources. The default value is correct for non-worker WPT, but standalone and * Base path for resources. The default value is correct for non-worker WPT, but standalone and
* workers must access resources using a different base path, so this is overridden in * workers must access resources using a different base path, so this is overridden in
* `test_worker-worker.ts` and `standalone.ts`. * `test_worker-worker.ts` and `standalone.ts`.
*/ let baseResourcePath = './resources'; */let baseResourcePath = './resources';let crossOriginHost = '';
let crossOriginHost = '';
function getAbsoluteBaseResourcePath(path) { function getAbsoluteBaseResourcePath(path) {
// Path is already an absolute one. // Path is already an absolute one.
@ -57,8 +56,8 @@ export function getCrossOriginResourcePath(pathRelativeToResourcesDir, onlineUrl
crossOriginHost + crossOriginHost +
getAbsoluteBaseResourcePath(baseResourcePath) + getAbsoluteBaseResourcePath(baseResourcePath) +
'/' + '/' +
pathRelativeToResourcesDir pathRelativeToResourcesDir);
);
} }
// Using 'localhost' and '127.0.0.1' trick to load cross origin resource. Set cross origin host name // Using 'localhost' and '127.0.0.1' trick to load cross origin resource. Set cross origin host name
@ -78,8 +77,8 @@ export function getCrossOriginResourcePath(pathRelativeToResourcesDir, onlineUrl
location.port + location.port +
getAbsoluteBaseResourcePath(baseResourcePath) + getAbsoluteBaseResourcePath(baseResourcePath) +
'/' + '/' +
pathRelativeToResourcesDir pathRelativeToResourcesDir);
);
} }
return onlineUrl; return onlineUrl;

View file

@ -1,11 +1,32 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ **/
export const globalTestConfig = { export const globalTestConfig = {
maxSubcasesInFlight: 500, maxSubcasesInFlight: 500,
testHeartbeatCallback: () => {}, testHeartbeatCallback: () => {},
noRaceWithRejectOnTimeout: false, noRaceWithRejectOnTimeout: false,
unrollConstEvalLoops: false, unrollConstEvalLoops: false,
compatibility: false, compatibility: false
}; };

View file

@ -1,3 +1,3 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ export { makeTestGroup } from '../internal/test_group.js'; **/export { makeTestGroup } from '../internal/test_group.js';

View file

@ -1,34 +1,88 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { assert } from '../util/util.js'; **/import { assert } from '../util/util.js';
import { parseQuery } from './query/parseQuery.js'; import { parseQuery } from './query/parseQuery.js';
import { loadTreeForQuery } from './tree.js'; import { loadTreeForQuery } from './tree.js';
// A listing file, e.g. either of: // A listing file, e.g. either of:
// - `src/webgpu/listing.ts` (which is dynamically computed, has a Promise<TestSuiteListing>) // - `src/webgpu/listing.ts` (which is dynamically computed, has a Promise<TestSuiteListing>)
// - `out/webgpu/listing.js` (which is pre-baked, has a TestSuiteListing) // - `out/webgpu/listing.js` (which is pre-baked, has a TestSuiteListing)
// A .spec.ts file, as imported.
// Override the types for addEventListener/removeEventListener so the callbacks can be used as
// strongly-typed.
// Base class for DefaultTestFileLoader and FakeTestFileLoader. // Base class for DefaultTestFileLoader and FakeTestFileLoader.
export class TestFileLoader extends EventTarget { export class TestFileLoader extends EventTarget {
async importSpecFile(suite, path) { async importSpecFile(suite, path) {
const url = `${suite}/${path.join('/')}.spec.js`; const url = `${suite}/${path.join('/')}.spec.js`;
this.dispatchEvent(new MessageEvent('import', { data: { url } })); this.dispatchEvent(new MessageEvent('import', { data: { url } }));
const ret = await this.import(url); const ret = await this.import(url);
this.dispatchEvent(new MessageEvent('imported', { data: { url } })); this.dispatchEvent(new MessageEvent('imported', { data: { url } }));
return ret; return ret;
} }
async loadTree(query, { subqueriesToExpand = [], maxChunkTime = Infinity } = {}) { async loadTree(
query,
{
subqueriesToExpand = [],
maxChunkTime = Infinity
} = {})
{
const tree = await loadTreeForQuery(this, query, { const tree = await loadTreeForQuery(this, query, {
subqueriesToExpand: subqueriesToExpand.map(s => { subqueriesToExpand: subqueriesToExpand.map((s) => {
const q = parseQuery(s); const q = parseQuery(s);
assert(q.level >= 2, () => `subqueriesToExpand entries should not be multi-file:\n ${q}`); assert(q.level >= 2, () => `subqueriesToExpand entries should not be multi-file:\n ${q}`);
return q; return q;
}), }),
maxChunkTime, maxChunkTime
}); });
this.dispatchEvent(new MessageEvent('finish')); this.dispatchEvent(new MessageEvent('finish'));
return tree; return tree;

View file

@ -1,7 +1,9 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { extractImportantStackTrace } from '../stack.js'; **/import { extractImportantStackTrace } from '../stack.js';
export class LogMessageWithStack extends Error { export class LogMessageWithStack extends Error {
stackHiddenMessage = undefined; stackHiddenMessage = undefined;
constructor(name, ex) { constructor(name, ex) {

View file

@ -1,11 +1,14 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { version } from '../version.js'; **/import { version } from '../version.js';
import { TestCaseRecorder } from './test_case_recorder.js'; import { TestCaseRecorder } from './test_case_recorder.js';
export class Logger { export class Logger {
static globalDebugMode = false; static globalDebugMode = false;
results = new Map(); results = new Map();
constructor({ overrideDebugMode } = {}) { constructor({ overrideDebugMode } = {}) {
@ -16,9 +19,9 @@ export class Logger {
const result = { status: 'running', timems: -1 }; const result = { status: 'running', timems: -1 };
this.results.set(name, result); this.results.set(name, result);
return [ return [
new TestCaseRecorder(result, this.overriddenDebugMode ?? Logger.globalDebugMode), new TestCaseRecorder(result, this.overriddenDebugMode ?? Logger.globalDebugMode),
result, result];
];
} }
asJSON(space) { asJSON(space) {

View file

@ -1,3 +1,4 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ export {}; **/ // MAINTENANCE_TODO: Add warn expectations
export {};

View file

@ -1,29 +1,45 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { SkipTestCase, UnexpectedPassError } from '../../framework/fixture.js'; **/import { SkipTestCase, UnexpectedPassError } from '../../framework/fixture.js';import { globalTestConfig } from '../../framework/test_config.js';import { now, assert } from '../../util/util.js';
import { globalTestConfig } from '../../framework/test_config.js';
import { now, assert } from '../../util/util.js'; import { LogMessageWithStack } from './log_message.js';var
LogSeverity = /*#__PURE__*/function (LogSeverity) {LogSeverity[LogSeverity["NotRun"] = 0] = "NotRun";LogSeverity[LogSeverity["Skip"] = 1] = "Skip";LogSeverity[LogSeverity["Pass"] = 2] = "Pass";LogSeverity[LogSeverity["Warn"] = 3] = "Warn";LogSeverity[LogSeverity["ExpectFailed"] = 4] = "ExpectFailed";LogSeverity[LogSeverity["ValidationFailed"] = 5] = "ValidationFailed";LogSeverity[LogSeverity["ThrewException"] = 6] = "ThrewException";return LogSeverity;}(LogSeverity || {});
import { LogMessageWithStack } from './log_message.js';
var LogSeverity;
(function (LogSeverity) {
LogSeverity[(LogSeverity['Pass'] = 0)] = 'Pass';
LogSeverity[(LogSeverity['Skip'] = 1)] = 'Skip';
LogSeverity[(LogSeverity['Warn'] = 2)] = 'Warn';
LogSeverity[(LogSeverity['ExpectFailed'] = 3)] = 'ExpectFailed';
LogSeverity[(LogSeverity['ValidationFailed'] = 4)] = 'ValidationFailed';
LogSeverity[(LogSeverity['ThrewException'] = 5)] = 'ThrewException';
})(LogSeverity || (LogSeverity = {}));
const kMaxLogStacks = 2; const kMaxLogStacks = 2;
const kMinSeverityForStack = LogSeverity.Warn; const kMinSeverityForStack = LogSeverity.Warn;
function logSeverityToString(status) {
switch (status) {
case LogSeverity.NotRun:
return 'notrun';
case LogSeverity.Pass:
return 'pass';
case LogSeverity.Skip:
return 'skip';
case LogSeverity.Warn:
return 'warn';
default:
return 'fail'; // Everything else is an error
}
}
/** Holds onto a LiveTestCaseResult owned by the Logger, and writes the results into it. */ /** Holds onto a LiveTestCaseResult owned by the Logger, and writes the results into it. */
export class TestCaseRecorder { export class TestCaseRecorder {
nonskippedSubcaseCount = 0; nonskippedSubcaseCount = 0;
inSubCase = false; inSubCase = false;
subCaseStatus = LogSeverity.Pass; subCaseStatus = LogSeverity.NotRun;
finalCaseStatus = LogSeverity.Pass; finalCaseStatus = LogSeverity.NotRun;
hideStacksBelowSeverity = kMinSeverityForStack; hideStacksBelowSeverity = kMinSeverityForStack;
startTime = -1; startTime = -1;
logs = []; logs = [];
@ -56,20 +72,13 @@ export class TestCaseRecorder {
} }
// Convert numeric enum back to string (but expose 'exception' as 'fail') // Convert numeric enum back to string (but expose 'exception' as 'fail')
this.result.status = this.result.status = logSeverityToString(this.finalCaseStatus);
this.finalCaseStatus === LogSeverity.Pass
? 'pass'
: this.finalCaseStatus === LogSeverity.Skip
? 'skip'
: this.finalCaseStatus === LogSeverity.Warn
? 'warn'
: 'fail'; // Everything else is an error
this.result.logs = this.logs; this.result.logs = this.logs;
} }
beginSubCase() { beginSubCase() {
this.subCaseStatus = LogSeverity.Pass; this.subCaseStatus = LogSeverity.NotRun;
this.inSubCase = true; this.inSubCase = true;
} }
@ -87,9 +96,7 @@ export class TestCaseRecorder {
} }
} finally { } finally {
this.inSubCase = false; this.inSubCase = false;
if (this.subCaseStatus > this.finalCaseStatus) { this.finalCaseStatus = Math.max(this.finalCaseStatus, this.subCaseStatus);
this.finalCaseStatus = this.subCaseStatus;
}
} }
} }
@ -103,7 +110,8 @@ export class TestCaseRecorder {
} }
info(ex) { info(ex) {
this.logImpl(LogSeverity.Pass, 'INFO', ex); // We need this to use the lowest LogSeverity so it doesn't override the current severity for this test case.
this.logImpl(LogSeverity.NotRun, 'INFO', ex);
} }
skipped(ex) { skipped(ex) {
@ -122,6 +130,14 @@ export class TestCaseRecorder {
this.logImpl(LogSeverity.ValidationFailed, 'VALIDATION FAILED', ex); this.logImpl(LogSeverity.ValidationFailed, 'VALIDATION FAILED', ex);
} }
passed() {
if (this.inSubCase) {
this.subCaseStatus = Math.max(this.subCaseStatus, LogSeverity.Pass);
} else {
this.finalCaseStatus = Math.max(this.finalCaseStatus, LogSeverity.Pass);
}
}
threw(ex) { threw(ex) {
if (ex instanceof SkipTestCase) { if (ex instanceof SkipTestCase) {
this.skipped(ex); this.skipped(ex);
@ -137,9 +153,9 @@ export class TestCaseRecorder {
// Final case status should be the "worst" of all log entries. // Final case status should be the "worst" of all log entries.
if (this.inSubCase) { if (this.inSubCase) {
if (level > this.subCaseStatus) this.subCaseStatus = level; this.subCaseStatus = Math.max(this.subCaseStatus, level);
} else { } else {
if (level > this.finalCaseStatus) this.finalCaseStatus = level; this.finalCaseStatus = Math.max(this.finalCaseStatus, level);
} }
// setFirstLineOnly for all logs except `kMaxLogStacks` stacks at the highest severity // setFirstLineOnly for all logs except `kMaxLogStacks` stacks at the highest severity

View file

@ -1,10 +1,24 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { assert } from '../util/util.js'; **/import { assert } from '../util/util.js';
import { comparePublicParamsPaths, Ordering } from './query/compare.js'; import { comparePublicParamsPaths, Ordering } from './query/compare.js';
import { kWildcard, kParamSeparator, kParamKVSeparator } from './query/separators.js'; import { kWildcard, kParamSeparator, kParamKVSeparator } from './query/separators.js';
export function paramKeyIsPublic(key) { export function paramKeyIsPublic(key) {
return !key.startsWith('_'); return !key.startsWith('_');
} }
@ -30,8 +44,55 @@ export function publicParamsEquals(x, y) {
return comparePublicParamsPaths(x, y) === Ordering.Equal; return comparePublicParamsPaths(x, y) === Ordering.Equal;
} }
/**
* Flatten a union of interfaces into a single interface encoding the same type.
*
* Flattens a union in such a way that:
* `{ a: number, b?: undefined } | { b: string, a?: undefined }`
* (which is the value type of `[{ a: 1 }, { b: 1 }]`)
* becomes `{ a: number | undefined, b: string | undefined }`.
*
* And also works for `{ a: number } | { b: string }` which maps to the same.
*/
function typeAssert() {} function typeAssert() {}
{ {
{ {
typeAssert(); typeAssert();
typeAssert(); typeAssert();
@ -53,6 +114,11 @@ function typeAssert() {}
} }
} }
/** Merges two objects into one `{ ...a, ...b }` and return it with a flattened type. */ /** Merges two objects into one `{ ...a, ...b }` and return it with a flattened type. */
export function mergeParams(a, b) { export function mergeParams(a, b) {
return { ...a, ...b }; return { ...a, ...b };
@ -68,6 +134,5 @@ export function mergeParamsChecked(a, b) {
Object.keys(merged).length === Object.keys(a).length + Object.keys(b).length, Object.keys(merged).length === Object.keys(a).length + Object.keys(b).length,
() => `Duplicate key between ${JSON.stringify(a)} and ${JSON.stringify(b)}` () => `Duplicate key between ${JSON.stringify(a)} and ${JSON.stringify(b)}`
); );
return merged; return merged;
} }

View file

@ -1,20 +1,21 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { assert, objectEquals } from '../../util/util.js'; **/import { assert, objectEquals } from '../../util/util.js';import { paramKeyIsPublic } from '../params_utils.js';
import { paramKeyIsPublic } from '../params_utils.js';
export let Ordering = /*#__PURE__*/function (Ordering) {Ordering[Ordering["Unordered"] = 0] = "Unordered";Ordering[Ordering["StrictSuperset"] = 1] = "StrictSuperset";Ordering[Ordering["Equal"] = 2] = "Equal";Ordering[Ordering["StrictSubset"] = 3] = "StrictSubset";return Ordering;}({});
export let Ordering;
/** /**
* Compares two queries for their ordering (which is used to build the tree). * Compares two queries for their ordering (which is used to build the tree).
* *
* See src/unittests/query_compare.spec.ts for examples. * See src/unittests/query_compare.spec.ts for examples.
*/ (function (Ordering) { */
Ordering[(Ordering['Unordered'] = 0)] = 'Unordered';
Ordering[(Ordering['StrictSuperset'] = 1)] = 'StrictSuperset';
Ordering[(Ordering['Equal'] = 2)] = 'Equal';
Ordering[(Ordering['StrictSubset'] = 3)] = 'StrictSubset';
})(Ordering || (Ordering = {}));
export function compareQueries(a, b) { export function compareQueries(a, b) {
if (a.suite !== b.suite) { if (a.suite !== b.suite) {
return Ordering.Unordered; return Ordering.Unordered;
@ -75,15 +76,16 @@ function comparePaths(a, b) {
} }
export function comparePublicParamsPaths(a, b) { export function comparePublicParamsPaths(a, b) {
const aKeys = Object.keys(a).filter(k => paramKeyIsPublic(k)); const aKeys = Object.keys(a).filter((k) => paramKeyIsPublic(k));
const commonKeys = new Set(aKeys.filter(k => k in b)); const commonKeys = new Set(aKeys.filter((k) => k in b));
for (const k of commonKeys) { for (const k of commonKeys) {
if (!objectEquals(a[k], b[k])) { // Treat +/-0.0 as different query by distinguishing them in objectEquals
if (!objectEquals(a[k], b[k], true)) {
return Ordering.Unordered; return Ordering.Unordered;
} }
} }
const bKeys = Object.keys(b).filter(k => paramKeyIsPublic(k)); const bKeys = Object.keys(b).filter((k) => paramKeyIsPublic(k));
const aRemainingKeys = aKeys.length - commonKeys.size; const aRemainingKeys = aKeys.length - commonKeys.size;
const bRemainingKeys = bKeys.length - commonKeys.size; const bRemainingKeys = bKeys.length - commonKeys.size;
if (aRemainingKeys === 0 && bRemainingKeys === 0) return Ordering.Equal; if (aRemainingKeys === 0 && bRemainingKeys === 0) return Ordering.Equal;

View file

@ -1,6 +1,6 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ /** **/ /**
* Encodes a stringified TestQuery so that it can be placed in a `?q=` parameter in a URL. * Encodes a stringified TestQuery so that it can be placed in a `?q=` parameter in a URL.
* *
* `encodeURIComponent` encodes in accordance with `application/x-www-form-urlencoded`, * `encodeURIComponent` encodes in accordance with `application/x-www-form-urlencoded`,
@ -8,8 +8,7 @@
* (we interpret this purely from JavaScript). * (we interpret this purely from JavaScript).
* So we encode the component, then selectively convert some %-encoded escape codes * So we encode the component, then selectively convert some %-encoded escape codes
* back to their original form for readability/copyability. * back to their original form for readability/copyability.
*/ export function encodeURIComponentSelectively(s) { */export function encodeURIComponentSelectively(s) {let ret = encodeURIComponent(s);
let ret = encodeURIComponent(s);
ret = ret.replace(/%22/g, '"'); // for JSON strings ret = ret.replace(/%22/g, '"'); // for JSON strings
ret = ret.replace(/%2C/g, ','); // for path separator, and JSON arrays ret = ret.replace(/%2C/g, ','); // for path separator, and JSON arrays
ret = ret.replace(/%3A/g, ':'); // for big separator ret = ret.replace(/%3A/g, ':'); // for big separator

View file

@ -1,6 +1,6 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { assert, sortObjectByKey, isPlainObject } from '../../util/util.js'; **/import { assert, sortObjectByKey, isPlainObject } from '../../util/util.js';
// JSON can't represent various values and by default stores them as `null`. // JSON can't represent various values and by default stores them as `null`.
// Instead, storing them as a magic string values in JSON. // Instead, storing them as a magic string values in JSON.
const jsUndefinedMagicValue = '_undef_'; const jsUndefinedMagicValue = '_undef_';
@ -17,23 +17,23 @@ const jsNegativeZeroMagicValue = '_negzero_';
const jsBigIntMagicPattern = /^(\d+)n$/; const jsBigIntMagicPattern = /^(\d+)n$/;
const toStringMagicValue = new Map([ const toStringMagicValue = new Map([
[undefined, jsUndefinedMagicValue], [undefined, jsUndefinedMagicValue],
[NaN, jsNaNMagicValue], [NaN, jsNaNMagicValue],
[Number.POSITIVE_INFINITY, jsPositiveInfinityMagicValue], [Number.POSITIVE_INFINITY, jsPositiveInfinityMagicValue],
[Number.NEGATIVE_INFINITY, jsNegativeInfinityMagicValue], [Number.NEGATIVE_INFINITY, jsNegativeInfinityMagicValue]
// No -0 handling because it is special cased. // No -0 handling because it is special cased.
]); ]);
const fromStringMagicValue = new Map([ const fromStringMagicValue = new Map([
[jsUndefinedMagicValue, undefined], [jsUndefinedMagicValue, undefined],
[jsNaNMagicValue, NaN], [jsNaNMagicValue, NaN],
[jsPositiveInfinityMagicValue, Number.POSITIVE_INFINITY], [jsPositiveInfinityMagicValue, Number.POSITIVE_INFINITY],
[jsNegativeInfinityMagicValue, Number.NEGATIVE_INFINITY], [jsNegativeInfinityMagicValue, Number.NEGATIVE_INFINITY],
// -0 is handled in this direction because there is no comparison issue. // -0 is handled in this direction because there is no comparison issue.
[jsNegativeZeroMagicValue, -0], [jsNegativeZeroMagicValue, -0]]
]); );
function stringifyFilter(k, v) { function stringifyFilter(_k, v) {
// Make sure no one actually uses a magic value as a parameter. // Make sure no one actually uses a magic value as a parameter.
if (typeof v === 'string') { if (typeof v === 'string') {
assert( assert(
@ -57,7 +57,7 @@ function stringifyFilter(k, v) {
assert( assert(
isPlainObject(v), isPlainObject(v),
`value must be a plain object but it appears to be a '${ `value must be a plain object but it appears to be a '${
Object.getPrototypeOf(v).constructor.name Object.getPrototypeOf(v).constructor.name
}` }`
); );
} }
@ -93,7 +93,7 @@ export function stringifyParamValueUniquely(value) {
// 'any' is part of the JSON.parse reviver interface, so cannot be avoided. // 'any' is part of the JSON.parse reviver interface, so cannot be avoided.
function parseParamValueReviver(k, v) { function parseParamValueReviver(_k, v) {
if (fromStringMagicValue.has(v)) { if (fromStringMagicValue.has(v)) {
return fromStringMagicValue.get(v); return fromStringMagicValue.get(v);
} }

View file

@ -1,15 +1,19 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { assert } from '../../util/util.js'; **/import { assert } from '../../util/util.js';import {
import { badParamValueChars, paramKeyIsPublic } from '../params_utils.js';
badParamValueChars,
paramKeyIsPublic } from
'../params_utils.js';
import { parseParamValue } from './json_param_value.js'; import { parseParamValue } from './json_param_value.js';
import { import {
TestQueryMultiFile, TestQueryMultiFile,
TestQueryMultiTest, TestQueryMultiTest,
TestQueryMultiCase, TestQueryMultiCase,
TestQuerySingleCase, TestQuerySingleCase } from
} from './query.js'; './query.js';
import { kBigSeparator, kWildcard, kPathSeparator, kParamSeparator } from './separators.js'; import { kBigSeparator, kWildcard, kPathSeparator, kParamSeparator } from './separators.js';
import { validQueryPart } from './validQueryPart.js'; import { validQueryPart } from './validQueryPart.js';
@ -61,7 +65,6 @@ function parseQueryImpl(s) {
`File-level query without wildcard ${kWildcard}. Did you want a file-level query \ `File-level query without wildcard ${kWildcard}. Did you want a file-level query \
(append ${kPathSeparator}${kWildcard}) or test-level query (append ${kBigSeparator}${kWildcard})?` (append ${kPathSeparator}${kWildcard}) or test-level query (append ${kBigSeparator}${kWildcard})?`
); );
return new TestQueryMultiFile(suite, file); return new TestQueryMultiFile(suite, file);
} }
assert(!filePathHasWildcard, `Wildcard ${kWildcard} must be at the end of the query string`); assert(!filePathHasWildcard, `Wildcard ${kWildcard} must be at the end of the query string`);
@ -75,7 +78,6 @@ function parseQueryImpl(s) {
`Test-level query without wildcard ${kWildcard}; did you want a test-level query \ `Test-level query without wildcard ${kWildcard}; did you want a test-level query \
(append ${kPathSeparator}${kWildcard}) or case-level query (append ${kBigSeparator}${kWildcard})?` (append ${kPathSeparator}${kWildcard}) or case-level query (append ${kBigSeparator}${kWildcard})?`
); );
assert(file.length > 0, 'File part of test-level query was empty (::)'); assert(file.length > 0, 'File part of test-level query was empty (::)');
return new TestQueryMultiTest(suite, file, test); return new TestQueryMultiTest(suite, file, test);
} }
@ -108,7 +110,10 @@ const kExampleQueries = `\
webgpu${kBigSeparator}a${kPathSeparator}b${kPathSeparator}${kWildcard} or \ webgpu${kBigSeparator}a${kPathSeparator}b${kPathSeparator}${kWildcard} or \
webgpu${kBigSeparator}a${kPathSeparator}b${kPathSeparator}c${kBigSeparator}${kWildcard}`; webgpu${kBigSeparator}a${kPathSeparator}b${kPathSeparator}c${kBigSeparator}${kWildcard}`;
function parseBigPart(s, separator) { function parseBigPart(
s,
separator)
{
if (s === '') { if (s === '') {
return { parts: [], wildcard: false }; return { parts: [], wildcard: false };
} }
@ -146,6 +151,5 @@ function parseSingleParamValue(s) {
!badParamValueChars.test(s), !badParamValueChars.test(s),
`param value must not match ${badParamValueChars} - was ${s}` `param value must not match ${badParamValueChars} - was ${s}`
); );
return parseParamValue(s); return parseParamValue(s);
} }

View file

@ -1,7 +1,7 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { optionEnabled } from '../../runtime/helper/options.js'; **/import { optionEnabled } from '../../runtime/helper/options.js';import { assert, unreachable } from '../../util/util.js';
import { assert, unreachable } from '../../util/util.js';
import { compareQueries, Ordering } from './compare.js'; import { compareQueries, Ordering } from './compare.js';
import { encodeURIComponentSelectively } from './encode_selectively.js'; import { encodeURIComponentSelectively } from './encode_selectively.js';
@ -15,6 +15,24 @@ import { stringifyPublicParams } from './stringify_params.js';
* TestQuery types are immutable. * TestQuery types are immutable.
*/ */
/**
* - 1 = MultiFile.
* - 2 = MultiTest.
* - 3 = MultiCase.
* - 4 = SingleCase.
*/
/** /**
* A multi-file test query, like `s:*` or `s:a,b,*`. * A multi-file test query, like `s:*` or `s:a,b,*`.
* *
@ -24,6 +42,8 @@ export class TestQueryMultiFile {
level = 1; level = 1;
isMultiFile = true; isMultiFile = true;
constructor(suite, file) { constructor(suite, file) {
this.suite = suite; this.suite = suite;
this.filePathParts = [...file]; this.filePathParts = [...file];
@ -52,6 +72,7 @@ export class TestQueryMultiTest extends TestQueryMultiFile {
isMultiFile = false; isMultiFile = false;
isMultiTest = true; isMultiTest = true;
constructor(suite, file, test) { constructor(suite, file, test) {
super(suite, file); super(suite, file);
assert(file.length > 0, 'multi-test (or finer) query must have file-path'); assert(file.length > 0, 'multi-test (or finer) query must have file-path');
@ -64,10 +85,10 @@ export class TestQueryMultiTest extends TestQueryMultiFile {
toStringHelper() { toStringHelper() {
return [ return [
this.suite, this.suite,
this.filePathParts.join(kPathSeparator), this.filePathParts.join(kPathSeparator),
[...this.testPathParts, kWildcard].join(kPathSeparator), [...this.testPathParts, kWildcard].join(kPathSeparator)];
];
} }
} }
@ -82,6 +103,7 @@ export class TestQueryMultiCase extends TestQueryMultiTest {
isMultiTest = false; isMultiTest = false;
isMultiCase = true; isMultiCase = true;
constructor(suite, file, test, params) { constructor(suite, file, test, params) {
super(suite, file, test); super(suite, file, test);
assert(test.length > 0, 'multi-case (or finer) query must have test-path'); assert(test.length > 0, 'multi-case (or finer) query must have test-path');
@ -94,11 +116,11 @@ export class TestQueryMultiCase extends TestQueryMultiTest {
toStringHelper() { toStringHelper() {
return [ return [
this.suite, this.suite,
this.filePathParts.join(kPathSeparator), this.filePathParts.join(kPathSeparator),
this.testPathParts.join(kPathSeparator), this.testPathParts.join(kPathSeparator),
stringifyPublicParams(this.params, true), stringifyPublicParams(this.params, true)];
];
} }
} }
@ -117,11 +139,11 @@ export class TestQuerySingleCase extends TestQueryMultiCase {
toStringHelper() { toStringHelper() {
return [ return [
this.suite, this.suite,
this.filePathParts.join(kPathSeparator), this.filePathParts.join(kPathSeparator),
this.testPathParts.join(kPathSeparator), this.testPathParts.join(kPathSeparator),
stringifyPublicParams(this.params), stringifyPublicParams(this.params)];
];
} }
} }
@ -138,11 +160,15 @@ export class TestQuerySingleCase extends TestQueryMultiCase {
* `suite:test_path:test_name:foo=1;bar=2;*`. * `suite:test_path:test_name:foo=1;bar=2;*`.
*/ */
export function parseExpectationsForTestQuery( export function parseExpectationsForTestQuery(
rawExpectations, rawExpectations,
query,
wptURL
) {
query,
wptURL)
{
if (!Array.isArray(rawExpectations)) { if (!Array.isArray(rawExpectations)) {
unreachable('Expectations should be an array'); unreachable('Expectations should be an array');
} }
@ -181,14 +207,14 @@ Expectation should be of the form path/to/cts.https.html?worker=0&q=suite:test_p
// Strip params from multicase expectations so that an expectation of foo=2;* // Strip params from multicase expectations so that an expectation of foo=2;*
// is stored if the test query is bar=3;* // is stored if the test query is bar=3;*
const queryForFilter = const queryForFilter =
expectationQuery instanceof TestQueryMultiCase expectationQuery instanceof TestQueryMultiCase ?
? new TestQueryMultiCase( new TestQueryMultiCase(
expectationQuery.suite, expectationQuery.suite,
expectationQuery.filePathParts, expectationQuery.filePathParts,
expectationQuery.testPathParts, expectationQuery.testPathParts,
{} {}
) ) :
: expectationQuery; expectationQuery;
if (compareQueries(query, queryForFilter) === Ordering.Unordered) { if (compareQueries(query, queryForFilter) === Ordering.Unordered) {
continue; continue;
@ -205,7 +231,7 @@ Expectation should be of the form path/to/cts.https.html?worker=0&q=suite:test_p
expectations.push({ expectations.push({
query: expectationQuery, query: expectationQuery,
expectation: entry.expectation, expectation: entry.expectation
}); });
} }
return expectations; return expectations;
@ -227,7 +253,6 @@ export function relativeQueryString(parent, child) {
childString.startsWith(parentString.substring(0, parentString.length - 2)), childString.startsWith(parentString.substring(0, parentString.length - 2)),
'impossible?: childString does not start with parentString[:-2]' 'impossible?: childString does not start with parentString[:-2]'
); );
return childString.substring(parentString.length - 2); return childString.substring(parentString.length - 2);
} else { } else {
unreachable( unreachable(

View file

@ -1,6 +1,6 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ /** Separator between big parts: suite:file:test:case */ export const kBigSeparator = ':'; **/ /** Separator between big parts: suite:file:test:case */export const kBigSeparator = ':';
/** Separator between path,to,file or path,to,test */ /** Separator between path,to,file or path,to,test */
export const kPathSeparator = ','; export const kPathSeparator = ',';

View file

@ -1,15 +1,14 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { assert } from '../../util/util.js'; **/import { assert } from '../../util/util.js';import { badParamValueChars, paramKeyIsPublic } from '../params_utils.js';
import { badParamValueChars, paramKeyIsPublic } from '../params_utils.js';
import { stringifyParamValue, stringifyParamValueUniquely } from './json_param_value.js'; import { stringifyParamValue, stringifyParamValueUniquely } from './json_param_value.js';
import { kParamKVSeparator, kParamSeparator, kWildcard } from './separators.js'; import { kParamKVSeparator, kParamSeparator, kWildcard } from './separators.js';
export function stringifyPublicParams(p, addWildcard = false) { export function stringifyPublicParams(p, addWildcard = false) {
const parts = Object.keys(p) const parts = Object.keys(p).
.filter(k => paramKeyIsPublic(k)) filter((k) => paramKeyIsPublic(k)).
.map(k => stringifySingleParam(k, p[k])); map((k) => stringifySingleParam(k, p[k]));
if (addWildcard) parts.push(kWildcard); if (addWildcard) parts.push(kWildcard);
@ -21,10 +20,10 @@ export function stringifyPublicParams(p, addWildcard = false) {
*/ */
export function stringifyPublicParamsUniquely(p) { export function stringifyPublicParamsUniquely(p) {
const keys = Object.keys(p).sort(); const keys = Object.keys(p).sort();
return keys return keys.
.filter(k => paramKeyIsPublic(k)) filter((k) => paramKeyIsPublic(k)).
.map(k => stringifySingleParamUniquely(k, p[k])) map((k) => stringifySingleParamUniquely(k, p[k])).
.join(kParamSeparator); join(kParamSeparator);
} }
export function stringifySingleParam(k, v) { export function stringifySingleParam(k, v) {
@ -41,6 +40,5 @@ function stringifySingleParamValue(v) {
!badParamValueChars.test(s), !badParamValueChars.test(s),
`JSON.stringified param value must not match ${badParamValueChars} - was ${s}` `JSON.stringified param value must not match ${badParamValueChars} - was ${s}`
); );
return s; return s;
} }

View file

@ -1,3 +1,3 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ /** Applies to group parts, test parts, params keys. */ export const validQueryPart = /^[a-zA-Z0-9_]+$/; **/ /** Applies to group parts, test parts, params keys. */export const validQueryPart = /^[a-zA-Z0-9_]+$/;

View file

@ -1,10 +1,8 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ // Returns the stack trace of an Error, but without the extra boilerplate at the bottom **/ // Returns the stack trace of an Error, but without the extra boilerplate at the bottom
// (e.g. RunCaseSpecific, processTicksAndRejections, etc.), for logging. // (e.g. RunCaseSpecific, processTicksAndRejections, etc.), for logging.
export function extractImportantStackTrace(e) { export function extractImportantStackTrace(e) {let stack = e.stack;if (!stack) {
let stack = e.stack;
if (!stack) {
return ''; return '';
} }
const redundantMessage = 'Error: ' + e.message + '\n'; const redundantMessage = 'Error: ' + e.message + '\n';

View file

@ -1,40 +1,105 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { SkipTestCase, UnexpectedPassError } from '../framework/fixture.js'; **/import {
SkipTestCase,
UnexpectedPassError } from
'../framework/fixture.js';
import { import {
builderIterateCasesWithSubcases, builderIterateCasesWithSubcases,
kUnitCaseParamsBuilder, kUnitCaseParamsBuilder } from
} from '../framework/params_builder.js';
'../framework/params_builder.js';
import { globalTestConfig } from '../framework/test_config.js'; import { globalTestConfig } from '../framework/test_config.js';
import { TestCaseRecorder } from '../internal/logging/test_case_recorder.js'; import { TestCaseRecorder } from '../internal/logging/test_case_recorder.js';
import { extractPublicParams, mergeParams } from '../internal/params_utils.js'; import { extractPublicParams, mergeParams } from '../internal/params_utils.js';
import { compareQueries, Ordering } from '../internal/query/compare.js'; import { compareQueries, Ordering } from '../internal/query/compare.js';
import { TestQuerySingleCase } from '../internal/query/query.js'; import {
TestQueryMultiTest,
TestQuerySingleCase } from
'../internal/query/query.js';
import { kPathSeparator } from '../internal/query/separators.js'; import { kPathSeparator } from '../internal/query/separators.js';
import { import {
stringifyPublicParams, stringifyPublicParams,
stringifyPublicParamsUniquely, stringifyPublicParamsUniquely } from
} from '../internal/query/stringify_params.js'; '../internal/query/stringify_params.js';
import { validQueryPart } from '../internal/query/validQueryPart.js'; import { validQueryPart } from '../internal/query/validQueryPart.js';
import { assert, unreachable } from '../util/util.js'; import { assert, unreachable } from '../util/util.js';
import { logToWebsocket } from './websocket_logger.js'; import { logToWebsocket } from './websocket_logger.js';
// Interface for defining tests
export function makeTestGroup(fixture) { export function makeTestGroup(fixture) {
return new TestGroup(fixture); return new TestGroup(fixture);
} }
// Interfaces for running tests // Interfaces for running tests
export function makeTestGroupForUnitTesting(fixture) {
export function makeTestGroupForUnitTesting(
fixture)
{
return new TestGroup(fixture); return new TestGroup(fixture);
} }
/** The maximum allowed length of a test query string. Checked by tools/validate. */
export const kQueryMaxLength = 375;
/** Parameter name for batch number (see also TestBuilder.batch). */ /** Parameter name for batch number (see also TestBuilder.batch). */
const kBatchParamName = 'batch__'; const kBatchParamName = 'batch__';
export class TestGroup { export class TestGroup {
seen = new Set(); seen = new Set();
tests = []; tests = [];
@ -53,7 +118,6 @@ export class TestGroup {
name === decodeURIComponent(name), name === decodeURIComponent(name),
`Not decodeURIComponent-idempotent: ${name} !== ${decodeURIComponent(name)}` `Not decodeURIComponent-idempotent: ${name} !== ${decodeURIComponent(name)}`
); );
assert(!this.seen.has(name), `Duplicate test name: ${name}`); assert(!this.seen.has(name), `Duplicate test name: ${name}`);
this.seen.add(name); this.seen.add(name);
@ -74,9 +138,14 @@ export class TestGroup {
return test; return test;
} }
validate() { validate(fileQuery) {
for (const test of this.tests) { for (const test of this.tests) {
test.validate(); const testQuery = new TestQueryMultiTest(
fileQuery.suite,
fileQuery.filePathParts,
test.testPath
);
test.validate(testQuery);
} }
} }
@ -91,7 +160,94 @@ export class TestGroup {
} }
} }
class TestBuilder { class TestBuilder {
testCases = undefined; testCases = undefined;
batchSize = 0; batchSize = 0;
@ -107,7 +263,7 @@ class TestBuilder {
return this; return this;
} }
specURL(url) { specURL(_url) {
return this; return this;
} }
@ -118,6 +274,7 @@ class TestBuilder {
} }
fn(fn) { fn(fn) {
// MAINTENANCE_TODO: add "TODO" if there's no description? (and make sure it only ends up on // MAINTENANCE_TODO: add "TODO" if there's no description? (and make sure it only ends up on
// actual tests, not on test parents in the tree, which is what happens if you do it here, not // actual tests, not on test parents in the tree, which is what happens if you do it here, not
// sure why) // sure why)
@ -134,7 +291,7 @@ class TestBuilder {
assert(this.testFn === undefined); assert(this.testFn === undefined);
this.description = this.description =
(this.description ? this.description + '\n\n' : '') + 'TODO: .unimplemented()'; (this.description ? this.description + '\n\n' : '') + 'TODO: .unimplemented()';
this.isUnimplemented = true; this.isUnimplemented = true;
this.testFn = () => { this.testFn = () => {
@ -143,7 +300,7 @@ class TestBuilder {
} }
/** Perform various validation/"lint" chenks. */ /** Perform various validation/"lint" chenks. */
validate() { validate(testQuery) {
const testPathString = this.testPath.join(kPathSeparator); const testPathString = this.testPath.join(kPathSeparator);
assert(this.testFn !== undefined, () => { assert(this.testFn !== undefined, () => {
let s = `Test is missing .fn(): ${testPathString}`; let s = `Test is missing .fn(): ${testPathString}`;
@ -153,12 +310,30 @@ class TestBuilder {
return s; return s;
}); });
assert(
testQuery.toString().length <= kQueryMaxLength,
() =>
`Test query ${testQuery} is too long. Max length is ${kQueryMaxLength} characters. Please shorten names or reduce parameters.`
);
if (this.testCases === undefined) { if (this.testCases === undefined) {
return; return;
} }
const seen = new Set(); const seen = new Set();
for (const [caseParams, subcases] of builderIterateCasesWithSubcases(this.testCases, null)) { for (const [caseParams, subcases] of builderIterateCasesWithSubcases(this.testCases, null)) {
const caseQuery = new TestQuerySingleCase(
testQuery.suite,
testQuery.filePathParts,
testQuery.testPathParts,
caseParams
).toString();
assert(
caseQuery.length <= kQueryMaxLength,
() =>
`Case query ${caseQuery} is too long. Max length is ${kQueryMaxLength} characters. Please shorten names or reduce parameters.`
);
for (const subcaseParams of subcases ?? [{}]) { for (const subcaseParams of subcases ?? [{}]) {
const params = mergeParams(caseParams, subcaseParams); const params = mergeParams(caseParams, subcaseParams);
assert(this.batchSize === 0 || !(kBatchParamName in params)); assert(this.batchSize === 0 || !(kBatchParamName in params));
@ -175,9 +350,8 @@ class TestBuilder {
const testcaseStringUnique = stringifyPublicParamsUniquely(params); const testcaseStringUnique = stringifyPublicParamsUniquely(params);
assert( assert(
!seen.has(testcaseStringUnique), !seen.has(testcaseStringUnique),
`Duplicate public test case params for test ${testPathString}: ${testcaseString}` `Duplicate public test case+subcase params for test ${testPathString}: ${testcaseString}`
); );
seen.add(testcaseStringUnique); seen.add(testcaseStringUnique);
} }
} }
@ -195,7 +369,9 @@ class TestBuilder {
return caseCount; return caseCount;
} }
params(cases) { params(
cases)
{
assert(this.testCases === undefined, 'test case is already parameterized'); assert(this.testCases === undefined, 'test case is already parameterized');
if (cases instanceof Function) { if (cases instanceof Function) {
this.testCases = cases(kUnitCaseParamsBuilder); this.testCases = cases(kUnitCaseParamsBuilder);
@ -211,7 +387,9 @@ class TestBuilder {
return this; return this;
} }
paramsSubcasesOnly(subcases) { paramsSubcasesOnly(
subcases)
{
if (subcases instanceof Function) { if (subcases instanceof Function) {
return this.params(subcases(kUnitCaseParamsBuilder.beginSubcases())); return this.params(subcases(kUnitCaseParamsBuilder.beginSubcases()));
} else { } else {
@ -265,7 +443,7 @@ class TestBuilder {
} }
// There are multiple batches. Helper function for this case: // There are multiple batches. Helper function for this case:
const makeCaseForBatch = batch => { const makeCaseForBatch = (batch) => {
const sliceStart = batch * this.batchSize; const sliceStart = batch * this.batchSize;
return this.makeCaseSpecific( return this.makeCaseSpecific(
{ ...caseParams, [kBatchParamName]: batch }, { ...caseParams, [kBatchParamName]: batch },
@ -288,16 +466,26 @@ class TestBuilder {
} }
class RunCaseSpecific { class RunCaseSpecific {
constructor( constructor(
testPath, testPath,
params, params,
isUnimplemented, isUnimplemented,
subcases, subcases,
fixture, fixture,
fn, fn,
beforeFn, beforeFn,
testCreationStack testCreationStack)
) { {
this.id = { test: testPath, params: extractPublicParams(params) }; this.id = { test: testPath, params: extractPublicParams(params) };
this.isUnimplemented = isUnimplemented; this.isUnimplemented = isUnimplemented;
this.params = params; this.params = params;
@ -320,7 +508,13 @@ class RunCaseSpecific {
} }
} }
async runTest(rec, sharedState, params, throwSkip, expectedStatus) { async runTest(
rec,
sharedState,
params,
throwSkip,
expectedStatus)
{
try { try {
rec.beginSubCase(); rec.beginSubCase();
if (expectedStatus === 'skip') { if (expectedStatus === 'skip') {
@ -331,6 +525,7 @@ class RunCaseSpecific {
try { try {
await inst.init(); await inst.init();
await this.fn(inst); await this.fn(inst);
rec.passed();
} finally { } finally {
// Runs as long as constructor succeeded, even if initialization or the test failed. // Runs as long as constructor succeeded, even if initialization or the test failed.
await inst.finalize(); await inst.finalize();
@ -340,10 +535,9 @@ class RunCaseSpecific {
// An error from init or test may have been a SkipTestCase. // An error from init or test may have been a SkipTestCase.
// An error from finalize may have been an eventualAsyncExpectation failure // An error from finalize may have been an eventualAsyncExpectation failure
// or unexpected validation/OOM error from the GPUDevice. // or unexpected validation/OOM error from the GPUDevice.
rec.threw(ex);
if (throwSkip && ex instanceof SkipTestCase) { if (throwSkip && ex instanceof SkipTestCase) {
throw ex; throw ex;
} else {
rec.threw(ex);
} }
} finally { } finally {
try { try {
@ -357,8 +551,12 @@ class RunCaseSpecific {
} }
} }
async run(rec, selfQuery, expectations) { async run(
const getExpectedStatus = selfQueryWithSubParams => { rec,
selfQuery,
expectations)
{
const getExpectedStatus = (selfQueryWithSubParams) => {
let didSeeFail = false; let didSeeFail = false;
for (const exp of expectations) { for (const exp of expectations) {
const ordering = compareQueries(exp.query, selfQueryWithSubParams); const ordering = compareQueries(exp.query, selfQueryWithSubParams);
@ -437,12 +635,13 @@ class RunCaseSpecific {
try { try {
arg.stack = stack; arg.stack = stack;
} catch { } catch {
// If that fails too, just silence it. // If that fails too, just silence it.
} }}
}
} }
} }
const rv = prop.apply(target, args); const rv = prop.apply(target, args);
// Because this proxy executes functions in a deferred manner, // Because this proxy executes functions in a deferred manner,
// it should never be used for functions that need to return a value. // it should never be used for functions that need to return a value.
@ -451,7 +650,7 @@ class RunCaseSpecific {
}; };
} }
return prop; return prop;
}, }
}); });
const params = mergeParams(this.params, subParams); const params = mergeParams(this.params, subParams);
@ -464,7 +663,7 @@ class RunCaseSpecific {
// Limit the maximum number of subcases in flight. // Limit the maximum number of subcases in flight.
if (subcasesInFlight >= maxSubcasesInFlight) { if (subcasesInFlight >= maxSubcasesInFlight) {
await new Promise(resolve => { await new Promise((resolve) => {
// There should only be one subcase waiting at a time. // There should only be one subcase waiting at a time.
assert(resolvePromiseBlockingSubcase === undefined); assert(resolvePromiseBlockingSubcase === undefined);
resolvePromiseBlockingSubcase = resolve; resolvePromiseBlockingSubcase = resolve;
@ -478,29 +677,28 @@ class RunCaseSpecific {
subRec, subRec,
sharedState, sharedState,
params, params,
/* throwSkip */ true, /* throwSkip */true,
getExpectedStatus(subcaseQuery) getExpectedStatus(subcaseQuery)
) ).
.then(() => { then(() => {
subRec.info(new Error('OK')); subRec.info(new Error('OK'));
}) }).
.catch(ex => { catch((ex) => {
if (ex instanceof SkipTestCase) { if (ex instanceof SkipTestCase) {
// Convert SkipTestCase to info messages // Convert SkipTestCase to info messages
ex.message = 'subcase skipped: ' + ex.message; ex.message = 'subcase skipped: ' + ex.message;
subRec.info(ex); subRec.info(ex);
++skipCount; ++skipCount;
} else { } else {
// Since we are catching all error inside runTest(), this should never happen // Since we are catching all error inside runTest(), this should never happen
subRec.threw(ex); subRec.threw(ex);
} }
}) }).
.finally(subcaseFinishedCallback); finally(subcaseFinishedCallback);
allPreviousSubcasesFinalizedPromise = allPreviousSubcasesFinalizedPromise.then( allPreviousSubcasesFinalizedPromise = allPreviousSubcasesFinalizedPromise.then(
() => finalizePromise () => finalizePromise
); );
++totalCount; ++totalCount;
} }
@ -515,7 +713,7 @@ class RunCaseSpecific {
rec, rec,
sharedState, sharedState,
this.params, this.params,
/* throwSkip */ false, /* throwSkip */false,
getExpectedStatus(selfQuery) getExpectedStatus(selfQuery)
); );
} }
@ -537,7 +735,7 @@ class RunCaseSpecific {
const msg = { const msg = {
q: selfQuery.toString(), q: selfQuery.toString(),
timems: rec.result.timems, timems: rec.result.timems,
nonskippedSubcaseCount: rec.nonskippedSubcaseCount, nonskippedSubcaseCount: rec.nonskippedSubcaseCount
}; };
logToWebsocket(JSON.stringify(msg)); logToWebsocket(JSON.stringify(msg));
} }

View file

@ -1,3 +1,6 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ export {}; **/ // A listing of all specs within a single suite. This is the (awaited) type of
// `groups` in '{cts,unittests}/listing.ts' and `listing` in the auto-generated
// 'out/{cts,unittests}/listing.js' files (see tools/gen_listings).
export {};

View file

@ -1,16 +1,18 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { loadMetadataForSuite } from '../framework/metadata.js'; **/import { loadMetadataForSuite } from '../framework/metadata.js';import { globalTestConfig } from '../framework/test_config.js';
import { globalTestConfig } from '../framework/test_config.js';
import { assert, now } from '../util/util.js'; import { assert, now } from '../util/util.js';
import { comparePublicParamsPaths, compareQueries, Ordering } from './query/compare.js'; import { comparePublicParamsPaths, compareQueries, Ordering } from './query/compare.js';
import { import {
TestQueryMultiCase, TestQueryMultiCase,
TestQuerySingleCase, TestQuerySingleCase,
TestQueryMultiFile, TestQueryMultiFile,
TestQueryMultiTest, TestQueryMultiTest } from
} from './query/query.js'; './query/query.js';
import { kBigSeparator, kWildcard, kPathSeparator, kParamSeparator } from './query/separators.js'; import { kBigSeparator, kWildcard, kPathSeparator, kParamSeparator } from './query/separators.js';
import { stringifySingleParam } from './query/stringify_params.js'; import { stringifySingleParam } from './query/stringify_params.js';
import { StacklessError } from './util.js'; import { StacklessError } from './util.js';
@ -39,6 +41,45 @@ import { StacklessError } from './util.js';
// - Enables developers to put any number of tests in one file as appropriate, without worrying // - Enables developers to put any number of tests in one file as appropriate, without worrying
// about expectation granularity. // about expectation granularity.
/**
* When iterating through "collapsed" tree nodes, indicates how many "query levels" to traverse
* through before starting to collapse nodes.
*
* Corresponds with TestQueryLevel, but excludes 4 (SingleCase):
* - 1 = MultiFile. Expands so every file is in the collapsed tree.
* - 2 = MultiTest. Expands so every test is in the collapsed tree.
* - 3 = MultiCase. Expands so every case is in the collapsed tree (i.e. collapsing disabled).
*/
export class TestTree { export class TestTree {
/** /**
* The `queryToLoad` that this test tree was created for. * The `queryToLoad` that this test tree was created for.
@ -49,6 +90,8 @@ export class TestTree {
* `TestQueryLevel` after `forQuery`. * `TestQueryLevel` after `forQuery`.
*/ */
constructor(forQuery, root) { constructor(forQuery, root) {
this.forQuery = forQuery; this.forQuery = forQuery;
this.root = root; this.root = root;
@ -58,7 +101,11 @@ export class TestTree {
); );
} }
static async create(forQuery, root, maxChunkTime) { static async create(
forQuery,
root,
maxChunkTime)
{
const suite = forQuery.suite; const suite = forQuery.suite;
let chunking = undefined; let chunking = undefined;
@ -81,13 +128,20 @@ export class TestTree {
iterateCollapsedNodes({ iterateCollapsedNodes({
includeIntermediateNodes = false, includeIntermediateNodes = false,
includeEmptySubtrees = false, includeEmptySubtrees = false,
alwaysExpandThroughLevel, alwaysExpandThroughLevel
}) { }) {
const expandThroughLevel = Math.max(this.forQuery.level, alwaysExpandThroughLevel); const expandThroughLevel = Math.max(this.forQuery.level, alwaysExpandThroughLevel);
return TestTree.iterateSubtreeNodes(this.root, { return TestTree.iterateSubtreeNodes(this.root, {
includeIntermediateNodes, includeIntermediateNodes,
includeEmptySubtrees, includeEmptySubtrees,
expandThroughLevel, expandThroughLevel
}); });
} }
@ -111,7 +165,14 @@ export class TestTree {
return TestTree.subtreeToString('(root)', this.root, ''); return TestTree.subtreeToString('(root)', this.root, '');
} }
static *iterateSubtreeNodes(subtree, opts) { static *iterateSubtreeNodes(
subtree,
opts)
{
if (opts.includeIntermediateNodes) { if (opts.includeIntermediateNodes) {
yield subtree; yield subtree;
} }
@ -144,7 +205,10 @@ export class TestTree {
} }
/** Propagate the subtreeTODOs/subtreeTests state upward from leaves to parent nodes. */ /** Propagate the subtreeTODOs/subtreeTests state upward from leaves to parent nodes. */
static async propagateCounts(subtree, chunking) { static async propagateCounts(
subtree,
chunking)
{
subtree.subtreeCounts ??= { tests: 0, nodesWithTODO: 0, totalTimeMS: 0 }; subtree.subtreeCounts ??= { tests: 0, nodesWithTODO: 0, totalTimeMS: 0 };
subtree.subcaseCount = 0; subtree.subcaseCount = 0;
for (const [, child] of subtree.children) { for (const [, child] of subtree.children) {
@ -200,8 +264,8 @@ export class TestTree {
static subtreeToString(name, tree, indent) { static subtreeToString(name, tree, indent) {
const collapsible = 'run' in tree ? '>' : tree.collapsible ? '+' : '-'; const collapsible = 'run' in tree ? '>' : tree.collapsible ? '+' : '-';
let s = let s =
indent + indent +
`${collapsible} ${TestTree.countsToString(tree)} ${JSON.stringify(name)} => ${tree.query}`; `${collapsible} ${TestTree.countsToString(tree)} ${JSON.stringify(name)} => ${tree.query}`;
if ('children' in tree) { if ('children' in tree) {
if (tree.description !== undefined) { if (tree.description !== undefined) {
s += `\n${indent} | ${JSON.stringify(tree.description)}`; s += `\n${indent} | ${JSON.stringify(tree.description)}`;
@ -218,10 +282,13 @@ export class TestTree {
// MAINTENANCE_TODO: Consider having subqueriesToExpand actually impact the depth-order of params // MAINTENANCE_TODO: Consider having subqueriesToExpand actually impact the depth-order of params
// in the tree. // in the tree.
export async function loadTreeForQuery( export async function loadTreeForQuery(
loader, loader,
queryToLoad, queryToLoad,
{ subqueriesToExpand, maxChunkTime = Infinity } {
) { subqueriesToExpand,
maxChunkTime = Infinity
})
{
const suite = queryToLoad.suite; const suite = queryToLoad.suite;
const specs = await loader.listing(suite); const specs = await loader.listing(suite);
@ -229,14 +296,14 @@ export async function loadTreeForQuery(
const seenSubqueriesToExpand = new Array(subqueriesToExpand.length); const seenSubqueriesToExpand = new Array(subqueriesToExpand.length);
seenSubqueriesToExpand.fill(false); seenSubqueriesToExpand.fill(false);
const isCollapsible = subquery => const isCollapsible = (subquery) =>
subqueriesToExpandEntries.every(([i, toExpand]) => { subqueriesToExpandEntries.every(([i, toExpand]) => {
const ordering = compareQueries(toExpand, subquery); const ordering = compareQueries(toExpand, subquery);
// If toExpand == subquery, no expansion is needed (but it's still "seen"). // If toExpand == subquery, no expansion is needed (but it's still "seen").
if (ordering === Ordering.Equal) seenSubqueriesToExpand[i] = true; if (ordering === Ordering.Equal) seenSubqueriesToExpand[i] = true;
return ordering !== Ordering.StrictSubset; return ordering !== Ordering.StrictSubset;
}); });
// L0 = suite-level, e.g. suite:* // L0 = suite-level, e.g. suite:*
// L1 = file-level, e.g. suite:a,b:* // L1 = file-level, e.g. suite:a,b:*
@ -271,7 +338,7 @@ export async function loadTreeForQuery(
} else { } else {
return { return {
...entry, ...entry,
importedSpec: await loader.importSpecFile(queryToLoad.suite, entry.file), importedSpec: await loader.importSpecFile(queryToLoad.suite, entry.file)
}; };
} }
})(); })();
@ -299,8 +366,11 @@ export async function loadTreeForQuery(
// readmeSubtree is suite:a,b,* // readmeSubtree is suite:a,b,*
// (This is always going to dedup with a file path, if there are any test spec files under // (This is always going to dedup with a file path, if there are any test spec files under
// the directory that has the README). // the directory that has the README).
const readmeSubtree = addSubtreeForDirPath(subtreeL0, entry.file, isCollapsible); const readmeSubtree = addSubtreeForDirPath(
subtreeL0,
entry.file,
isCollapsible
);
setSubtreeDescriptionAndCountTODOs(readmeSubtree, entry.readme); setSubtreeDescriptionAndCountTODOs(readmeSubtree, entry.readme);
continue; continue;
} }
@ -308,8 +378,11 @@ export async function loadTreeForQuery(
// Entry is a spec file. // Entry is a spec file.
const spec = entry.importedSpec; const spec = entry.importedSpec;
// subtreeL1 is suite:a,b:* // subtreeL1 is suite:a,b:*
const subtreeL1 = addSubtreeForFilePath(subtreeL0, entry.file, isCollapsible); const subtreeL1 = addSubtreeForFilePath(
subtreeL0,
entry.file,
isCollapsible
);
setSubtreeDescriptionAndCountTODOs(subtreeL1, spec.description); setSubtreeDescriptionAndCountTODOs(subtreeL1, spec.description);
let groupHasTests = false; let groupHasTests = false;
@ -331,7 +404,6 @@ export async function loadTreeForQuery(
t.testCreationStack, t.testCreationStack,
isCollapsible isCollapsible
); );
// This is 1 test. Set tests=1 then count TODOs. // This is 1 test. Set tests=1 then count TODOs.
subtreeL2.subtreeCounts ??= { tests: 1, nodesWithTODO: 0, totalTimeMS: 0 }; subtreeL2.subtreeCounts ??= { tests: 1, nodesWithTODO: 0, totalTimeMS: 0 };
if (t.description) setSubtreeDescriptionAndCountTODOs(subtreeL2, t.description); if (t.description) setSubtreeDescriptionAndCountTODOs(subtreeL2, t.description);
@ -380,7 +452,10 @@ export async function loadTreeForQuery(
return TestTree.create(queryToLoad, subtreeL0, maxChunkTime); return TestTree.create(queryToLoad, subtreeL0, maxChunkTime);
} }
function setSubtreeDescriptionAndCountTODOs(subtree, description) { function setSubtreeDescriptionAndCountTODOs(
subtree,
description)
{
assert(subtree.description === undefined); assert(subtree.description === undefined);
subtree.description = description.trim(); subtree.description = description.trim();
subtree.subtreeCounts ??= { tests: 0, nodesWithTODO: 0, totalTimeMS: 0 }; subtree.subtreeCounts ??= { tests: 0, nodesWithTODO: 0, totalTimeMS: 0 };
@ -389,17 +464,24 @@ function setSubtreeDescriptionAndCountTODOs(subtree, description) {
} }
} }
function makeTreeForSuite(suite, isCollapsible) { function makeTreeForSuite(
suite,
isCollapsible)
{
const query = new TestQueryMultiFile(suite, []); const query = new TestQueryMultiFile(suite, []);
return { return {
readableRelativeName: suite + kBigSeparator, readableRelativeName: suite + kBigSeparator,
query, query,
children: new Map(), children: new Map(),
collapsible: isCollapsible(query), collapsible: isCollapsible(query)
}; };
} }
function addSubtreeForDirPath(tree, file, isCollapsible) { function addSubtreeForDirPath(
tree,
file,
isCollapsible)
{
const subqueryFile = []; const subqueryFile = [];
// To start, tree is suite:* // To start, tree is suite:*
// This loop goes from that -> suite:a,* -> suite:a,b,* // This loop goes from that -> suite:a,* -> suite:a,b,*
@ -410,14 +492,18 @@ function addSubtreeForDirPath(tree, file, isCollapsible) {
return { return {
readableRelativeName: part + kPathSeparator + kWildcard, readableRelativeName: part + kPathSeparator + kWildcard,
query, query,
collapsible: isCollapsible(query), collapsible: isCollapsible(query)
}; };
}); });
} }
return tree; return tree;
} }
function addSubtreeForFilePath(tree, file, isCollapsible) { function addSubtreeForFilePath(
tree,
file,
isCollapsible)
{
// To start, tree is suite:* // To start, tree is suite:*
// This goes from that -> suite:a,* -> suite:a,b,* // This goes from that -> suite:a,* -> suite:a,b,*
tree = addSubtreeForDirPath(tree, file, isCollapsible); tree = addSubtreeForDirPath(tree, file, isCollapsible);
@ -428,13 +514,18 @@ function addSubtreeForFilePath(tree, file, isCollapsible) {
return { return {
readableRelativeName: file[file.length - 1] + kBigSeparator + kWildcard, readableRelativeName: file[file.length - 1] + kBigSeparator + kWildcard,
query, query,
collapsible: isCollapsible(query), collapsible: isCollapsible(query)
}; };
}); });
return subtree; return subtree;
} }
function addSubtreeForTestPath(tree, test, testCreationStack, isCollapsible) { function addSubtreeForTestPath(
tree,
test,
testCreationStack,
isCollapsible)
{
const subqueryTest = []; const subqueryTest = [];
// To start, tree is suite:a,b:* // To start, tree is suite:a,b:*
// This loop goes from that -> suite:a,b:c,* -> suite:a,b:c,d,* // This loop goes from that -> suite:a,b:c,* -> suite:a,b:c,d,*
@ -446,11 +537,10 @@ function addSubtreeForTestPath(tree, test, testCreationStack, isCollapsible) {
tree.query.filePathParts, tree.query.filePathParts,
subqueryTest subqueryTest
); );
return { return {
readableRelativeName: part + kPathSeparator + kWildcard, readableRelativeName: part + kPathSeparator + kWildcard,
query, query,
collapsible: isCollapsible(query), collapsible: isCollapsible(query)
}; };
}); });
} }
@ -462,19 +552,22 @@ function addSubtreeForTestPath(tree, test, testCreationStack, isCollapsible) {
subqueryTest, subqueryTest,
{} {}
); );
assert(subqueryTest.length > 0, 'subqueryTest is empty'); assert(subqueryTest.length > 0, 'subqueryTest is empty');
return { return {
readableRelativeName: subqueryTest[subqueryTest.length - 1] + kBigSeparator + kWildcard, readableRelativeName: subqueryTest[subqueryTest.length - 1] + kBigSeparator + kWildcard,
kWildcard, kWildcard,
query, query,
testCreationStack, testCreationStack,
collapsible: isCollapsible(query), collapsible: isCollapsible(query)
}; };
}); });
} }
function addLeafForCase(tree, t, checkCollapsible) { function addLeafForCase(
tree,
t,
checkCollapsible)
{
const query = tree.query; const query = tree.query;
let name = ''; let name = '';
const subqueryParams = {}; const subqueryParams = {};
@ -492,11 +585,10 @@ function addLeafForCase(tree, t, checkCollapsible) {
query.testPathParts, query.testPathParts,
subqueryParams subqueryParams
); );
return { return {
readableRelativeName: name + kParamSeparator + kWildcard, readableRelativeName: name + kParamSeparator + kWildcard,
query: subquery, query: subquery,
collapsible: checkCollapsible(subquery), collapsible: checkCollapsible(subquery)
}; };
}); });
} }
@ -508,12 +600,15 @@ function addLeafForCase(tree, t, checkCollapsible) {
query.testPathParts, query.testPathParts,
subqueryParams subqueryParams
); );
checkCollapsible(subquery); // mark seenSubqueriesToExpand checkCollapsible(subquery); // mark seenSubqueriesToExpand
insertLeaf(tree, subquery, t); insertLeaf(tree, subquery, t);
} }
function getOrInsertSubtree(key, parent, createSubtree) { function getOrInsertSubtree(
key,
parent,
createSubtree)
{
let v; let v;
const child = parent.children.get(key); const child = parent.children.get(key);
if (child !== undefined) { if (child !== undefined) {
@ -532,7 +627,7 @@ function insertLeaf(parent, query, t) {
query, query,
run: (rec, expectations) => t.run(rec, query, expectations || []), run: (rec, expectations) => t.run(rec, query, expectations || []),
isUnimplemented: t.isUnimplemented, isUnimplemented: t.isUnimplemented,
subcaseCount: t.computeSubcaseCount(), subcaseCount: t.computeSubcaseCount()
}; };
// This is a leaf (e.g. s:f:t:x=1;* -> s:f:t:x=1). The key is always ''. // This is a leaf (e.g. s:f:t:x=1;* -> s:f:t:x=1). The key is always ''.
@ -544,7 +639,7 @@ function insertLeaf(parent, query, t) {
function dissolveSingleChildTrees(tree) { function dissolveSingleChildTrees(tree) {
if ('children' in tree) { if ('children' in tree) {
const shouldDissolveThisTree = const shouldDissolveThisTree =
tree.children.size === 1 && tree.query.depthInLevel !== 0 && tree.description === undefined; tree.children.size === 1 && tree.query.depthInLevel !== 0 && tree.description === undefined;
if (shouldDissolveThisTree) { if (shouldDissolveThisTree) {
// Loops exactly once // Loops exactly once
for (const [, child] of tree.children) { for (const [, child] of tree.children) {

View file

@ -1,10 +1,9 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ /** **/ /**
* Error without a stack, which can be used to fatally exit from `tool/` scripts with a * Error without a stack, which can be used to fatally exit from `tool/` scripts with a
* user-friendly message (and no confusing stack). * user-friendly message (and no confusing stack).
*/ export class StacklessError extends Error { */export class StacklessError extends Error {constructor(message) {
constructor(message) {
super(message); super(message);
this.stack = undefined; this.stack = undefined;
} }

View file

@ -1,3 +1,3 @@
// AUTO-GENERATED - DO NOT EDIT. See tools/gen_version. // AUTO-GENERATED - DO NOT EDIT. See tools/gen_version.
export const version = 'f2b59e03621238d0d0fd6305be2c406ce3e45ac2'; export const version = 'ae15a59832989c22982acaeaccdf5d379afced62';

View file

@ -1,11 +1,11 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ /** **/ /**
* - 'uninitialized' means we haven't tried to connect yet * - 'uninitialized' means we haven't tried to connect yet
* - Promise means it's pending * - Promise means it's pending
* - 'failed' means it failed (this is the most common case, where the logger isn't running) * - 'failed' means it failed (this is the most common case, where the logger isn't running)
* - WebSocket means it succeeded * - WebSocket means it succeeded
*/ let connection = 'uninitialized'; */let connection = 'uninitialized';
/** /**
* Log a string to a websocket at `localhost:59497`. See `tools/websocket-logger`. * Log a string to a websocket at `localhost:59497`. See `tools/websocket-logger`.
@ -18,7 +18,7 @@ export function logToWebsocket(msg) {
} }
if (connection === 'uninitialized') { if (connection === 'uninitialized') {
connection = new Promise(resolve => { connection = new Promise((resolve) => {
if (typeof WebSocket === 'undefined') { if (typeof WebSocket === 'undefined') {
resolve('failed'); resolve('failed');
return; return;
@ -37,7 +37,7 @@ export function logToWebsocket(msg) {
resolve('failed'); resolve('failed');
}; };
}); });
void connection.then(resolved => { void connection.then((resolved) => {
connection = resolved; connection = resolved;
}); });
} }

View file

@ -1,19 +1,23 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ let windowURL = undefined; **/let windowURL = undefined;function getWindowURL() {if (windowURL === undefined) {
function getWindowURL() {
if (windowURL === undefined) {
windowURL = new URL(window.location.toString()); windowURL = new URL(window.location.toString());
} }
return windowURL; return windowURL;
} }
export function optionEnabled(opt, searchParams = getWindowURL().searchParams) { export function optionEnabled(
opt,
searchParams = getWindowURL().searchParams)
{
const val = searchParams.get(opt); const val = searchParams.get(opt);
return val !== null && val !== '0'; return val !== null && val !== '0';
} }
export function optionString(opt, searchParams = getWindowURL().searchParams) { export function optionString(
opt,
searchParams = getWindowURL().searchParams)
{
return searchParams.get(opt) || ''; return searchParams.get(opt) || '';
} }
@ -21,18 +25,36 @@ export function optionString(opt, searchParams = getWindowURL().searchParams) {
* The possible options for the tests. * The possible options for the tests.
*/ */
export const kDefaultCTSOptions = { export const kDefaultCTSOptions = {
worker: false, worker: false,
debug: true, debug: true,
compatibility: false, compatibility: false,
unrollConstEvalLoops: false, unrollConstEvalLoops: false,
powerPreference: '', powerPreference: ''
}; };
/** /**
* Extra per option info. * Extra per option info.
*/ */
/**
* Type for info for every option. This definition means adding an option
* will generate a compile time error if no extra info is provided.
*/
/** /**
* Options to the CTS. * Options to the CTS.
*/ */
@ -45,11 +67,11 @@ export const kCTSOptionsInfo = {
description: 'set default powerPreference for some tests', description: 'set default powerPreference for some tests',
parser: optionString, parser: optionString,
selectValueDescriptions: [ selectValueDescriptions: [
{ value: '', description: 'default' }, { value: '', description: 'default' },
{ value: 'low-power', description: 'low-power' }, { value: 'low-power', description: 'low-power' },
{ value: 'high-performance', description: 'high-performance' }, { value: 'high-performance', description: 'high-performance' }]
],
}, }
}; };
/** /**
@ -59,16 +81,19 @@ export const kCTSOptionsInfo = {
* parseHTMLFile -> parse_html_file * parseHTMLFile -> parse_html_file
*/ */
export function camelCaseToSnakeCase(id) { export function camelCaseToSnakeCase(id) {
return id return id.
.replace(/(.)([A-Z][a-z]+)/g, '$1_$2') replace(/(.)([A-Z][a-z]+)/g, '$1_$2').
.replace(/([a-z0-9])([A-Z])/g, '$1_$2') replace(/([a-z0-9])([A-Z])/g, '$1_$2').
.toLowerCase(); toLowerCase();
} }
/** /**
* Creates a Options from search parameters. * Creates a Options from search parameters.
*/ */
function getOptionsInfoFromSearchString(optionsInfos, searchString) { function getOptionsInfoFromSearchString(
optionsInfos,
searchString)
{
const searchParams = new URLSearchParams(searchString); const searchParams = new URLSearchParams(searchString);
const optionValues = {}; const optionValues = {};
for (const [optionName, info] of Object.entries(optionsInfos)) { for (const [optionName, info] of Object.entries(optionsInfos)) {
@ -82,7 +107,13 @@ function getOptionsInfoFromSearchString(optionsInfos, searchString) {
* Given a test query string in the form of `suite:foo,bar,moo&opt1=val1&opt2=val2 * Given a test query string in the form of `suite:foo,bar,moo&opt1=val1&opt2=val2
* returns the query and the options. * returns the query and the options.
*/ */
export function parseSearchParamLikeWithOptions(optionsInfos, query) { export function parseSearchParamLikeWithOptions(
optionsInfos,
query)
{
const searchString = query.includes('q=') || query.startsWith('?') ? query : `q=${query}`; const searchString = query.includes('q=') || query.startsWith('?') ? query : `q=${query}`;
const queries = new URLSearchParams(searchString).getAll('q'); const queries = new URLSearchParams(searchString).getAll('q');
const options = getOptionsInfoFromSearchString(optionsInfos, searchString); const options = getOptionsInfoFromSearchString(optionsInfos, searchString);

View file

@ -1,19 +1,23 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { setBaseResourcePath } from '../../framework/resources.js'; **/import { setBaseResourcePath } from '../../framework/resources.js';import { globalTestConfig } from '../../framework/test_config.js';import { DefaultTestFileLoader } from '../../internal/file_loader.js';
import { globalTestConfig } from '../../framework/test_config.js';
import { DefaultTestFileLoader } from '../../internal/file_loader.js';
import { Logger } from '../../internal/logging/logger.js'; import { Logger } from '../../internal/logging/logger.js';
import { parseQuery } from '../../internal/query/parseQuery.js'; import { parseQuery } from '../../internal/query/parseQuery.js';
import { setDefaultRequestAdapterOptions } from '../../util/navigator_gpu.js'; import { setDefaultRequestAdapterOptions } from '../../util/navigator_gpu.js';
import { assert } from '../../util/util.js'; import { assert } from '../../util/util.js';
// Should be DedicatedWorkerGlobalScope, but importing lib "webworker" conflicts with lib "dom".
const loader = new DefaultTestFileLoader(); const loader = new DefaultTestFileLoader();
setBaseResourcePath('../../../resources'); setBaseResourcePath('../../../resources');
self.onmessage = async ev => { self.onmessage = async (ev) => {
const query = ev.data.query; const query = ev.data.query;
const expectations = ev.data.expectations; const expectations = ev.data.expectations;
const ctsOptions = ev.data.ctsOptions; const ctsOptions = ev.data.ctsOptions;
@ -29,7 +33,7 @@ self.onmessage = async ev => {
setDefaultRequestAdapterOptions({ setDefaultRequestAdapterOptions({
...(powerPreference && { powerPreference }), ...(powerPreference && { powerPreference }),
// MAINTENANCE_TODO: Change this to whatever the option ends up being // MAINTENANCE_TODO: Change this to whatever the option ends up being
...(compatibility && { compatibilityMode: true }), ...(compatibility && { compatibilityMode: true })
}); });
} }

View file

@ -1,10 +1,13 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { LogMessageWithStack } from '../../internal/logging/log_message.js'; **/import { LogMessageWithStack } from '../../internal/logging/log_message.js';
import { kDefaultCTSOptions } from './options.js'; import { kDefaultCTSOptions } from './options.js';
export class TestWorker { export class TestWorker {
resolvers = new Map(); resolvers = new Map();
constructor(ctsOptions) { constructor(ctsOptions) {
@ -13,7 +16,7 @@ export class TestWorker {
const selfPathDir = selfPath.substring(0, selfPath.lastIndexOf('/')); const selfPathDir = selfPath.substring(0, selfPath.lastIndexOf('/'));
const workerPath = selfPathDir + '/test_worker-worker.js'; const workerPath = selfPathDir + '/test_worker-worker.js';
this.worker = new Worker(workerPath, { type: 'module' }); this.worker = new Worker(workerPath, { type: 'module' });
this.worker.onmessage = ev => { this.worker.onmessage = (ev) => {
const query = ev.data.query; const query = ev.data.query;
const result = ev.data.result; const result = ev.data.result;
if (result.logs) { if (result.logs) {
@ -28,13 +31,17 @@ export class TestWorker {
}; };
} }
async run(rec, query, expectations = []) { async run(
rec,
query,
expectations = [])
{
this.worker.postMessage({ this.worker.postMessage({
query, query,
expectations, expectations,
ctsOptions: this.ctsOptions, ctsOptions: this.ctsOptions
}); });
const workerResult = await new Promise(resolve => { const workerResult = await new Promise((resolve) => {
this.resolvers.set(query, resolve); this.resolvers.set(query, resolve);
}); });
rec.injectResult(workerResult); rec.injectResult(workerResult);

View file

@ -1,8 +1,7 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ // Implements the wpt-embedded test runner (see also: wpt/cts.https.html). **/ // Implements the wpt-embedded test runner (see also: wpt/cts.https.html).
import { globalTestConfig } from '../framework/test_config.js'; import { globalTestConfig } from '../framework/test_config.js';import { DefaultTestFileLoader } from '../internal/file_loader.js';
import { DefaultTestFileLoader } from '../internal/file_loader.js';
import { prettyPrintLog } from '../internal/logging/log_message.js'; import { prettyPrintLog } from '../internal/logging/log_message.js';
import { Logger } from '../internal/logging/logger.js'; import { Logger } from '../internal/logging/logger.js';
import { parseQuery } from '../internal/query/parseQuery.js'; import { parseQuery } from '../internal/query/parseQuery.js';
@ -14,10 +13,21 @@ import { TestWorker } from './helper/test_worker.js';
// testharness.js API (https://web-platform-tests.org/writing-tests/testharness-api.html) // testharness.js API (https://web-platform-tests.org/writing-tests/testharness-api.html)
setup({ setup({
// It's convenient for us to asynchronously add tests to the page. Prevent done() from being // It's convenient for us to asynchronously add tests to the page. Prevent done() from being
// called implicitly when the page is finished loading. // called implicitly when the page is finished loading.
explicit_done: true, explicit_done: true
}); });
void (async () => { void (async () => {
@ -27,7 +37,7 @@ void (async () => {
globalTestConfig.unrollConstEvalLoops = optionEnabled('unroll_const_eval_loops'); globalTestConfig.unrollConstEvalLoops = optionEnabled('unroll_const_eval_loops');
const failOnWarnings = const failOnWarnings =
typeof shouldWebGPUCTSFailOnWarnings !== 'undefined' && (await shouldWebGPUCTSFailOnWarnings); typeof shouldWebGPUCTSFailOnWarnings !== 'undefined' && (await shouldWebGPUCTSFailOnWarnings);
const loader = new DefaultTestFileLoader(); const loader = new DefaultTestFileLoader();
const qs = new URLSearchParams(window.location.search).getAll('q'); const qs = new URLSearchParams(window.location.search).getAll('q');
@ -36,13 +46,13 @@ void (async () => {
const testcases = await loader.loadCases(filterQuery); const testcases = await loader.loadCases(filterQuery);
const expectations = const expectations =
typeof loadWebGPUExpectations !== 'undefined' typeof loadWebGPUExpectations !== 'undefined' ?
? parseExpectationsForTestQuery( parseExpectationsForTestQuery(
await loadWebGPUExpectations, await loadWebGPUExpectations,
filterQuery, filterQuery,
new URL(window.location.href) new URL(window.location.href)
) ) :
: []; [];
const log = new Logger(); const log = new Logger();
@ -60,7 +70,7 @@ void (async () => {
} }
// Unfortunately, it seems not possible to surface any logs for warn/skip. // Unfortunately, it seems not possible to surface any logs for warn/skip.
if (res.status === 'fail' || (res.status === 'warn' && failOnWarnings)) { if (res.status === 'fail' || res.status === 'warn' && failOnWarnings) {
const logs = (res.logs ?? []).map(prettyPrintLog); const logs = (res.logs ?? []).map(prettyPrintLog);
assert_unreached('\n' + logs.join('\n') + '\n'); assert_unreached('\n' + logs.join('\n') + '\n');
} }

View file

@ -1,6 +1,7 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { resolveOnTimeout } from './util.js'; **/import { resolveOnTimeout } from './util.js';
/** /**
* Attempts to trigger JavaScript garbage collection, either using explicit methods if exposed * Attempts to trigger JavaScript garbage collection, either using explicit methods if exposed
@ -8,6 +9,7 @@
* some weird tricks to incur GC pressure. Adopted from the WebGL CTS. * some weird tricks to incur GC pressure. Adopted from the WebGL CTS.
*/ */
export async function attemptGarbageCollection() { export async function attemptGarbageCollection() {
const w = globalThis; const w = globalThis;
if (w.GCController) { if (w.GCController) {
w.GCController.collect(); w.GCController.collect();
@ -20,11 +22,12 @@ export async function attemptGarbageCollection() {
} }
try { try {
w.QueryInterface(Components.interfaces.nsIInterfaceRequestor) w.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
.getInterface(Components.interfaces.nsIDOMWindowUtils) getInterface(Components.interfaces.nsIDOMWindowUtils).
.garbageCollect(); garbageCollect();
return; return;
} catch (e) { } catch (e) {
// ignore any failure // ignore any failure
} }
if (w.gc) { if (w.gc) {

View file

@ -1,6 +1,69 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ **/ /**
* The interface used for formatting strings to contain color metadata.
*
* Use the interface properties to construct a style, then use the
* `(s: string): string` function to format the provided string with the given
* style.
*/
/** /**
* The interface used for formatting strings with color metadata. * The interface used for formatting strings with color metadata.
@ -13,9 +76,10 @@
export let Colors; export let Colors;
try { try {
Colors = require('ansi-colors'); Colors = require('ansi-colors');
} catch { } catch {
const passthrough = s => s; const passthrough = (s) => s;
passthrough.enabled = false; passthrough.enabled = false;
passthrough.reset = passthrough; passthrough.reset = passthrough;
passthrough.bold = passthrough; passthrough.bold = passthrough;

View file

@ -0,0 +1,57 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ /// CRC32 immutable lookup table data.
const kCRC32LUT = [0, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064,
0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8,
0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa,
0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac,
0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e,
0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2,
0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6,
0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158,
0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c,
0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e,
0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320,
0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12,
0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76,
0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8,
0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda,
0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c,
0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0,
0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82,
0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4,
0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6,
0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a,
0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c,
0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e,
0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d];
/**
* @param str the input string
* @returns the CRC32 of the input string
* @see https://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRC-32_algorithm
*/
export function crc32(str) {
const utf8 = new TextEncoder().encode(str);
const u32 = new Uint32Array(1);
u32[0] = 0xffffffff;
for (const c of utf8) {
u32[0] = u32[0] >>> 8 ^ kCRC32LUT[u32[0] & 0xff ^ c];
}
u32[0] = u32[0] ^ 0xffffffff;
return u32[0];
}
/** @returns the input number has a 8-character hex string */
export function toHexString(number) {
return ('00000000' + number.toString(16)).slice(-8);
}

View file

@ -1,17 +1,17 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ **/
export function keysOf(obj) { export function keysOf(obj) {
return Object.keys(obj); return Object.keys(obj);
} }
export function numericKeysOf(obj) { export function numericKeysOf(obj) {
return Object.keys(obj).map(n => Number(n)); return Object.keys(obj).map((n) => Number(n));
} }
/** /**
* @returns a new Record from @p objects, using the string returned by Object.toString() as the keys * @returns a new Record from `objects`, using the string returned by Object.toString() as the keys
* and the objects as the values. * and the objects as the values.
*/ */
export function objectsToRecord(objects) { export function objectsToRecord(objects) {
@ -19,7 +19,7 @@ export function objectsToRecord(objects) {
return objects.reduce((obj, type) => { return objects.reduce((obj, type) => {
return { return {
...obj, ...obj,
[type.toString()]: type, [type.toString()]: type
}; };
}, record); }, record);
} }
@ -29,7 +29,17 @@ export function objectsToRecord(objects) {
* *
* Note: Using `as const` on the arguments to this function is necessary to infer the correct type. * Note: Using `as const` on the arguments to this function is necessary to infer the correct type.
*/ */
export function makeTable(members, defaults, table) { export function makeTable(
members,
defaults,
table)
{
const result = {}; const result = {};
for (const [k, v] of Object.entries(table)) { for (const [k, v] of Object.entries(table)) {
const item = {}; const item = {};
@ -85,15 +95,27 @@ export function makeTable(members, defaults, table) {
* @param defaults the default value by column for any element in a row of the table that is undefined * @param defaults the default value by column for any element in a row of the table that is undefined
* @param table named table rows. * @param table named table rows.
*/ */
export function makeTableRenameAndFilter(columnRenames, columnsKept, columns, defaults, table) { export function makeTableRenameAndFilter(
columnRenames,
columnsKept,
columns,
defaults,
table)
{
const result = {}; const result = {};
const keyToIndex = new Map( const keyToIndex = new Map(
columnsKept.map(name => { columnsKept.map((name) => {
const remappedName = columnRenames[name] === undefined ? name : columnRenames[name]; const remappedName = columnRenames[name] === undefined ? name : columnRenames[name];
return [name, columns.indexOf(remappedName)]; return [name, columns.indexOf(remappedName)];
}) })
); );
for (const [k, v] of Object.entries(table)) { for (const [k, v] of Object.entries(table)) {
const item = {}; const item = {};
for (const member of columnsKept) { for (const member of columnsKept) {

View file

@ -1,6 +1,6 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ **/ /// <reference types="@webgpu/types" />
import { ErrorWithExtra, assert, objectEquals } from './util.js'; import { ErrorWithExtra, assert, objectEquals } from './util.js';
@ -13,7 +13,6 @@ function defaultGPUProvider() {
typeof navigator !== 'undefined' && navigator.gpu !== undefined, typeof navigator !== 'undefined' && navigator.gpu !== undefined,
'No WebGPU implementation found' 'No WebGPU implementation found'
); );
return navigator.gpu; return navigator.gpu;
} }
@ -22,6 +21,7 @@ function defaultGPUProvider() {
* May throw an exception if a GPU cannot be created. * May throw an exception if a GPU cannot be created.
*/ */
let gpuProvider = defaultGPUProvider; let gpuProvider = defaultGPUProvider;
/** /**
@ -63,11 +63,14 @@ export function getGPU(recorder) {
impl = gpuProvider(); impl = gpuProvider();
if (defaultRequestAdapterOptions) { if (defaultRequestAdapterOptions) {
const oldFn = impl.requestAdapter; const oldFn = impl.requestAdapter;
impl.requestAdapter = function (options) { impl.requestAdapter = function (
options)
{
const promise = oldFn.call(this, { ...defaultRequestAdapterOptions, ...options }); const promise = oldFn.call(this, { ...defaultRequestAdapterOptions, ...options });
if (recorder) { if (recorder) {
void promise.then(async adapter => { void promise.then(async (adapter) => {
if (adapter) { if (adapter) {
const info = await adapter.requestAdapterInfo(); const info = await adapter.requestAdapterInfo();
const infoString = `Adapter: ${info.vendor} / ${info.architecture} / ${info.device}`; const infoString = `Adapter: ${info.vendor} / ${info.architecture} / ${info.device}`;

View file

@ -0,0 +1,36 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ /**
* Parses all the paths of the typescript `import` statements from content
* @param path the current path of the file
* @param content the file content
* @returns the list of import paths
*/export function parseImports(path, content) {const out = [];
const importRE = /^import\s[^'"]*(['"])([./\w]*)(\1);/gm;
let importMatch;
while (importMatch = importRE.exec(content)) {
const importPath = importMatch[2].replace(`'`, '').replace(`"`, '');
out.push(joinPath(path, importPath));
}
return out;
}
function joinPath(a, b) {
const aParts = a.split('/');
const bParts = b.split('/');
aParts.pop(); // remove file
let bStart = 0;
while (aParts.length > 0) {
switch (bParts[bStart]) {
case '.':
bStart++;
continue;
case '..':
aParts.pop();
bStart++;
continue;
}
break;
}
return [...aParts, ...bParts.slice(bStart)].join('/');
}

View file

@ -1,21 +1,21 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { assert } from './util.js'; // The state of the preprocessor is a stack of States. **/import { assert } from './util.js'; // The state of the preprocessor is a stack of States.
var State; var
State = /*#__PURE__*/function (State) {State[State["Seeking"] = 0] = "Seeking";State[State["Passing"] = 1] = "Passing";State[State["Skipping"] = 2] = "Skipping";return State;}(State || {});
// Have already seen a passing condition; now skipping the rest // Have already seen a passing condition; now skipping the rest
// The transitions in the state space are the following preprocessor directives: // The transitions in the state space are the following preprocessor directives:
// - Sibling elif // - Sibling elif
// - Sibling else // - Sibling else
// - Sibling endif // - Sibling endif
// - Child if // - Child if
(function (State) {
State[(State['Seeking'] = 0)] = 'Seeking';
State[(State['Passing'] = 1)] = 'Passing';
State[(State['Skipping'] = 2)] = 'Skipping';
})(State || (State = {}));
class Directive { class Directive {
constructor(depth) { constructor(depth) {
this.depth = depth; this.depth = depth;
} }
@ -26,9 +26,13 @@ class Directive {
`Number of "$"s must match nesting depth, currently ${stack.length} (e.g. $if $$if $$endif $endif)` `Number of "$"s must match nesting depth, currently ${stack.length} (e.g. $if $$if $$endif $endif)`
); );
} }
} }
class If extends Directive { class If extends Directive {
constructor(depth, predicate) { constructor(depth, predicate) {
super(depth); super(depth);
this.predicate = predicate; this.predicate = predicate;
@ -40,11 +44,11 @@ class If extends Directive {
stack.push({ stack.push({
allowsFollowingElse: true, allowsFollowingElse: true,
state: state:
parentState !== State.Passing parentState !== State.Passing ?
? State.Skipping State.Skipping :
: this.predicate this.predicate ?
? State.Passing State.Passing :
: State.Seeking, State.Seeking
}); });
} }
} }
@ -71,7 +75,7 @@ class Else extends Directive {
assert(allowsFollowingElse, 'pp.else after pp.else'); assert(allowsFollowingElse, 'pp.else after pp.else');
stack.push({ stack.push({
allowsFollowingElse: false, allowsFollowingElse: false,
state: siblingState === State.Seeking ? State.Passing : State.Skipping, state: siblingState === State.Seeking ? State.Passing : State.Skipping
}); });
} }
} }
@ -103,7 +107,10 @@ class EndIf extends Directive {
* @param strings - The array of constant string chunks of the template string. * @param strings - The array of constant string chunks of the template string.
* @param ...values - The array of interpolated `${}` values within the template string. * @param ...values - The array of interpolated `${}` values within the template string.
*/ */
export function pp(strings, ...values) { export function pp(
strings,
...values)
{
let result = ''; let result = '';
const stateStack = [{ allowsFollowingElse: false, state: State.Passing }]; const stateStack = [{ allowsFollowingElse: false, state: State.Passing }];
@ -127,16 +134,16 @@ export function pp(strings, ...values) {
return result; return result;
} }
pp._if = predicate => new If(1, predicate); pp._if = (predicate) => new If(1, predicate);
pp._elif = predicate => new ElseIf(1, predicate); pp._elif = (predicate) => new ElseIf(1, predicate);
pp._else = new Else(1); pp._else = new Else(1);
pp._endif = new EndIf(1); pp._endif = new EndIf(1);
pp.__if = predicate => new If(2, predicate); pp.__if = (predicate) => new If(2, predicate);
pp.__elif = predicate => new ElseIf(2, predicate); pp.__elif = (predicate) => new ElseIf(2, predicate);
pp.__else = new Else(2); pp.__else = new Else(2);
pp.__endif = new EndIf(2); pp.__endif = new EndIf(2);
pp.___if = predicate => new If(3, predicate); pp.___if = (predicate) => new If(3, predicate);
pp.___elif = predicate => new ElseIf(3, predicate); pp.___elif = (predicate) => new ElseIf(3, predicate);
pp.___else = new Else(3); pp.___else = new Else(3);
pp.___endif = new EndIf(3); pp.___endif = new EndIf(3);
// Add more if needed. // Add more if needed.

View file

@ -1,6 +1,6 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ **/ /** Defined by WPT. Like `setTimeout`, but applies a timeout multiplier for slow test systems. */
/** /**
* Equivalent of `setTimeout`, but redirects to WPT's `step_timeout` when it is defined. * Equivalent of `setTimeout`, but redirects to WPT's `step_timeout` when it is defined.
*/ */

View file

@ -1,8 +1,56 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ **/ /** Forces a type to resolve its type definitions, to make it readable/debuggable. */
/** Returns the type `true` iff X and Y are exactly equal */
export function assertTypeTrue() {} export function assertTypeTrue() {}
/** `ReadonlyArray` of `ReadonlyArray`s. */
/** `ReadonlyArray` of `ReadonlyArray`s of `ReadonlyArray`s. */
/**
* Deep version of the Readonly<> type, with support for tuples (up to length 7).
* <https://gist.github.com/masterkidan/7322752f569b1bba53e0426266768623>
*/
/** /**
* Computes the intersection of a set of types, given the union of those types. * Computes the intersection of a set of types, given the union of those types.
@ -10,4 +58,40 @@ export function assertTypeTrue() {}
* From: https://stackoverflow.com/a/56375136 * From: https://stackoverflow.com/a/56375136
*/ */
/** "Type asserts" that `X` is a subtype of `Y`. */
/**
* Zips a key tuple type and a value tuple type together into an object.
*
* @template Keys Keys of the resulting object.
* @template Values Values of the resulting object. If a key corresponds to a `Values` member that
* is undefined or past the end, it defaults to the corresponding `Defaults` member.
* @template Defaults Default values. If a key corresponds to a `Defaults` member that is past the
* end, the default falls back to `undefined`.
*/
// K exhausted // K exhausted

View file

@ -1,8 +1,6 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { Float16Array } from '../../external/petamoriken/float16/float16.js'; **/import { Float16Array } from '../../external/petamoriken/float16/float16.js';import { SkipTestCase } from '../framework/fixture.js';import { globalTestConfig } from '../framework/test_config.js';
import { SkipTestCase } from '../framework/fixture.js';
import { globalTestConfig } from '../framework/test_config.js';
import { Logger } from '../internal/logging/logger.js'; import { Logger } from '../internal/logging/logger.js';
import { keysOf } from './data_tables.js'; import { keysOf } from './data_tables.js';
@ -13,19 +11,22 @@ import { timeout } from './timeout.js';
* The extra data is omitted if not running the test in debug mode (`?debug=1`). * The extra data is omitted if not running the test in debug mode (`?debug=1`).
*/ */
export class ErrorWithExtra extends Error { export class ErrorWithExtra extends Error {
/** /**
* `extra` function is only called if in debug mode. * `extra` function is only called if in debug mode.
* If an `ErrorWithExtra` is passed, its message is used and its extras are passed through. * If an `ErrorWithExtra` is passed, its message is used and its extras are passed through.
*/ */
constructor(baseOrMessage, newExtra) { constructor(baseOrMessage, newExtra) {
const message = typeof baseOrMessage === 'string' ? baseOrMessage : baseOrMessage.message; const message = typeof baseOrMessage === 'string' ? baseOrMessage : baseOrMessage.message;
super(message); super(message);
const oldExtras = baseOrMessage instanceof ErrorWithExtra ? baseOrMessage.extra : {}; const oldExtras = baseOrMessage instanceof ErrorWithExtra ? baseOrMessage.extra : {};
this.extra = Logger.globalDebugMode this.extra = Logger.globalDebugMode ?
? { ...oldExtras, ...newExtra() } { ...oldExtras, ...newExtra() } :
: { omitted: 'pass ?debug=1' }; { omitted: 'pass ?debug=1' };
} }
} }
@ -46,15 +47,29 @@ export function assertOK(value) {
return value; return value;
} }
/** Options for assertReject, shouldReject, and friends. */
/** /**
* Resolves if the provided promise rejects; rejects if it does not. * Resolves if the provided promise rejects; rejects if it does not.
*/ */
export async function assertReject(p, msg) { export async function assertReject(
expectedName,
p,
{ allowMissingStack = false, message } = {})
{
try { try {
await p; await p;
unreachable(msg); unreachable(message);
} catch (ex) { } catch (ex) {
// Assertion OK // Asserted as expected
if (!allowMissingStack) {
const m = message ? ` (${message})` : '';
assert(
ex instanceof Error && typeof ex.stack === 'string',
'threw as expected, but missing stack' + m
);
}
} }
} }
@ -89,7 +104,7 @@ export function now() {
* Returns a promise which resolves after the specified time. * Returns a promise which resolves after the specified time.
*/ */
export function resolveOnTimeout(ms) { export function resolveOnTimeout(ms) {
return new Promise(resolve => { return new Promise((resolve) => {
timeout(() => { timeout(() => {
resolve(); resolve();
}, ms); }, ms);
@ -133,15 +148,19 @@ export function raceWithRejectOnTimeout(p, ms, msg) {
* Takes a promise `p` and returns a new one which rejects if `p` resolves or rejects, * Takes a promise `p` and returns a new one which rejects if `p` resolves or rejects,
* and otherwise resolves after the specified time. * and otherwise resolves after the specified time.
*/ */
export function assertNotSettledWithinTime(p, ms, msg) { export function assertNotSettledWithinTime(
p,
ms,
msg)
{
// Rejects regardless of whether p resolves or rejects. // Rejects regardless of whether p resolves or rejects.
const rejectWhenSettled = p.then(() => Promise.reject(new Error(msg))); const rejectWhenSettled = p.then(() => Promise.reject(new Error(msg)));
// Resolves after `ms` milliseconds. // Resolves after `ms` milliseconds.
const timeoutPromise = new Promise(resolve => { const timeoutPromise = new Promise((resolve) => {
const handle = timeout(() => { const handle = timeout(() => {
resolve(undefined); resolve(undefined);
}, ms); }, ms);
p.finally(() => clearTimeout(handle)); void p.finally(() => clearTimeout(handle));
}); });
return Promise.race([rejectWhenSettled, timeoutPromise]); return Promise.race([rejectWhenSettled, timeoutPromise]);
} }
@ -177,14 +196,24 @@ export function sortObjectByKey(v) {
/** /**
* Determines whether two JS values are equal, recursing into objects and arrays. * Determines whether two JS values are equal, recursing into objects and arrays.
* NaN is treated specially, such that `objectEquals(NaN, NaN)`. * NaN is treated specially, such that `objectEquals(NaN, NaN)`. +/-0.0 are treated as equal
* by default, but can be opted to be distinguished.
* @param x the first JS values that get compared
* @param y the second JS values that get compared
* @param distinguishSignedZero if set to true, treat 0.0 and -0.0 as unequal. Default to false.
*/ */
export function objectEquals(x, y) { export function objectEquals(
x,
y,
distinguishSignedZero = false)
{
if (typeof x !== 'object' || typeof y !== 'object') { if (typeof x !== 'object' || typeof y !== 'object') {
if (typeof x === 'number' && typeof y === 'number' && Number.isNaN(x) && Number.isNaN(y)) { if (typeof x === 'number' && typeof y === 'number' && Number.isNaN(x) && Number.isNaN(y)) {
return true; return true;
} }
return x === y; // Object.is(0.0, -0.0) is false while (0.0 === -0.0) is true. Other than +/-0.0 and NaN cases,
// Object.is works in the same way as ===.
return distinguishSignedZero ? Object.is(x, y) : x === y;
} }
if (x === null || y === null) return x === y; if (x === null || y === null) return x === y;
if (x.constructor !== y.constructor) return false; if (x.constructor !== y.constructor) return false;
@ -199,7 +228,7 @@ export function objectEquals(x, y) {
const x1 = x; const x1 = x;
const y1 = y; const y1 = y;
const p = Object.keys(x); const p = Object.keys(x);
return Object.keys(y).every(i => p.indexOf(i) !== -1) && p.every(i => objectEquals(x1[i], y1[i])); return Object.keys(y).every((i) => p.indexOf(i) !== -1) && p.every((i) => objectEquals(x1[i], y1[i]));
} }
/** /**
@ -225,14 +254,14 @@ export function mapLazy(xs, f) {
for (const x of xs) { for (const x of xs) {
yield f(x); yield f(x);
} }
}, }
}; };
} }
const ReorderOrders = { const ReorderOrders = {
forward: true, forward: true,
backward: true, backward: true,
shiftByHalf: true, shiftByHalf: true
}; };
export const kReorderOrderKeys = keysOf(ReorderOrders); export const kReorderOrderKeys = keysOf(ReorderOrders);
@ -243,7 +272,7 @@ export const kReorderOrderKeys = keysOf(ReorderOrders);
*/ */
export function shiftByHalf(arr) { export function shiftByHalf(arr) {
const len = arr.length; const len = arr.length;
const half = (len / 2) | 0; const half = len / 2 | 0;
const firstHalf = arr.splice(0, half); const firstHalf = arr.splice(0, half);
return [...arr, ...firstHalf]; return [...arr, ...firstHalf];
} }
@ -257,38 +286,82 @@ export function reorder(order, arr) {
return arr.slice(); return arr.slice();
case 'backward': case 'backward':
return arr.slice().reverse(); return arr.slice().reverse();
case 'shiftByHalf': { case 'shiftByHalf':{
// should this be pseudo random? // should this be pseudo random?
return shiftByHalf(arr); return shiftByHalf(arr);
} }
} }
} }
const TypedArrayBufferViewInstances = [ const TypedArrayBufferViewInstances = [
new Uint8Array(), new Uint8Array(),
new Uint8ClampedArray(), new Uint8ClampedArray(),
new Uint16Array(), new Uint16Array(),
new Uint32Array(), new Uint32Array(),
new Int8Array(), new Int8Array(),
new Int16Array(), new Int16Array(),
new Int32Array(), new Int32Array(),
new Float16Array(), new Float16Array(),
new Float32Array(), new Float32Array(),
new Float64Array(), new Float64Array()];
];
export const kTypedArrayBufferViews = {
export const kTypedArrayBufferViews =
{
...(() => { ...(() => {
const result = {}; const result = {};
for (const v of TypedArrayBufferViewInstances) { for (const v of TypedArrayBufferViewInstances) {
result[v.constructor.name] = v.constructor; result[v.constructor.name] = v.constructor;
} }
return result; return result;
})(), })()
}; };
export const kTypedArrayBufferViewKeys = keysOf(kTypedArrayBufferViews); export const kTypedArrayBufferViewKeys = keysOf(kTypedArrayBufferViews);
export const kTypedArrayBufferViewConstructors = Object.values(kTypedArrayBufferViews); export const kTypedArrayBufferViewConstructors = Object.values(kTypedArrayBufferViews);
/** /**
* Creates a case parameter for a typedarray. * Creates a case parameter for a typedarray.
* *
@ -318,23 +391,34 @@ export const kTypedArrayBufferViewConstructors = Object.values(kTypedArrayBuffer
* }) * })
* ``` * ```
*/ */
export function typedArrayParam(type, data) { export function typedArrayParam(
type,
data)
{
return { type, data }; return { type, data };
} }
export function createTypedArray(type, data) { export function createTypedArray(
type,
data)
{
return new kTypedArrayBufferViews[type](data); return new kTypedArrayBufferViews[type](data);
} }
/** /**
* Converts a TypedArrayParam to a typedarray. See typedArrayParam * Converts a TypedArrayParam to a typedarray. See typedArrayParam
*/ */
export function typedArrayFromParam(param) { export function typedArrayFromParam(
param)
{
const { type, data } = param; const { type, data } = param;
return createTypedArray(type, data); return createTypedArray(type, data);
} }
function subarrayAsU8(buf, { start = 0, length }) { function subarrayAsU8(
buf,
{ start = 0, length })
{
if (buf instanceof ArrayBuffer) { if (buf instanceof ArrayBuffer) {
return new Uint8Array(buf, start, length); return new Uint8Array(buf, start, length);
} else if (buf instanceof Uint8Array || buf instanceof Uint8ClampedArray) { } else if (buf instanceof Uint8Array || buf instanceof Uint8ClampedArray) {
@ -345,9 +429,9 @@ function subarrayAsU8(buf, { start = 0, length }) {
} }
const byteOffset = buf.byteOffset + start * buf.BYTES_PER_ELEMENT; const byteOffset = buf.byteOffset + start * buf.BYTES_PER_ELEMENT;
const byteLength = const byteLength =
length !== undefined length !== undefined ?
? length * buf.BYTES_PER_ELEMENT length * buf.BYTES_PER_ELEMENT :
: buf.byteLength - (byteOffset - buf.byteOffset); buf.byteLength - (byteOffset - buf.byteOffset);
return new Uint8Array(buf.buffer, byteOffset, byteLength); return new Uint8Array(buf.buffer, byteOffset, byteLength);
} }
@ -356,7 +440,10 @@ function subarrayAsU8(buf, { start = 0, length }) {
* *
* `start`/`length` are in elements (or in bytes, if ArrayBuffer). * `start`/`length` are in elements (or in bytes, if ArrayBuffer).
*/ */
export function memcpy(src, dst) { export function memcpy(
src,
dst)
{
subarrayAsU8(dst.dst, dst).set(subarrayAsU8(src.src, src)); subarrayAsU8(dst.dst, dst).set(subarrayAsU8(src.src, src));
} }
@ -365,11 +452,17 @@ export function memcpy(src, dst) {
* by a constant and then adding a constant to it. * by a constant and then adding a constant to it.
*/ */
/** /**
* Filters out SpecValues that are the same. * Filters out SpecValues that are the same.
*/ */
export function filterUniqueValueTestVariants(valueTestVariants) { export function filterUniqueValueTestVariants(valueTestVariants) {
return new Map(valueTestVariants.map(v => [`m:${v.mult},a:${v.add}`, v])).values(); return new Map(
valueTestVariants.map((v) => [`m:${v.mult},a:${v.add}`, v])
).values();
} }
/** /**

View file

@ -1,6 +1,6 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ import { timeout } from './timeout.js'; // Copied from https://github.com/web-platform-tests/wpt/blob/master/common/reftest-wait.js **/import { timeout } from './timeout.js'; // Copied from https://github.com/web-platform-tests/wpt/blob/master/common/reftest-wait.js
/** /**
* Remove the `reftest-wait` class on the document element. * Remove the `reftest-wait` class on the document element.

View file

@ -44,6 +44,7 @@
<meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:limits,unknown:*'> <meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:limits,unknown:*'>
<meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:limits,supported:*'> <meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:limits,supported:*'>
<meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:limit,better_than_supported:*'> <meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:limit,better_than_supported:*'>
<meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:limit,out_of_range:*'>
<meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:limit,worse_than_default:*'> <meta name=variant content='?q=webgpu:api,operation,adapter,requestDevice:limit,worse_than_default:*'>
<meta name=variant content='?q=webgpu:api,operation,buffers,map:mapAsync,write:*'> <meta name=variant content='?q=webgpu:api,operation,buffers,map:mapAsync,write:*'>
<meta name=variant content='?q=webgpu:api,operation,buffers,map:mapAsync,write,unchanged_ranges_preserved:*'> <meta name=variant content='?q=webgpu:api,operation,buffers,map:mapAsync,write,unchanged_ranges_preserved:*'>
@ -141,8 +142,11 @@
<meta name=variant content='?q=webgpu:api,operation,queue,writeBuffer:array_types:*'> <meta name=variant content='?q=webgpu:api,operation,queue,writeBuffer:array_types:*'>
<meta name=variant content='?q=webgpu:api,operation,queue,writeBuffer:multiple_writes_at_different_offsets_and_sizes:*'> <meta name=variant content='?q=webgpu:api,operation,queue,writeBuffer:multiple_writes_at_different_offsets_and_sizes:*'>
<meta name=variant content='?q=webgpu:api,operation,reflection:buffer_reflection_attributes:*'> <meta name=variant content='?q=webgpu:api,operation,reflection:buffer_reflection_attributes:*'>
<meta name=variant content='?q=webgpu:api,operation,reflection:buffer_creation_from_reflection:*'>
<meta name=variant content='?q=webgpu:api,operation,reflection:texture_reflection_attributes:*'> <meta name=variant content='?q=webgpu:api,operation,reflection:texture_reflection_attributes:*'>
<meta name=variant content='?q=webgpu:api,operation,reflection:texture_creation_from_reflection:*'>
<meta name=variant content='?q=webgpu:api,operation,reflection:query_set_reflection_attributes:*'> <meta name=variant content='?q=webgpu:api,operation,reflection:query_set_reflection_attributes:*'>
<meta name=variant content='?q=webgpu:api,operation,reflection:query_set_creation_from_reflection:*'>
<meta name=variant content='?q=webgpu:api,operation,render_pass,clear_value:stored:*'> <meta name=variant content='?q=webgpu:api,operation,render_pass,clear_value:stored:*'>
<meta name=variant content='?q=webgpu:api,operation,render_pass,clear_value:loaded:*'> <meta name=variant content='?q=webgpu:api,operation,render_pass,clear_value:loaded:*'>
<meta name=variant content='?q=webgpu:api,operation,render_pass,clear_value:srgb:*'> <meta name=variant content='?q=webgpu:api,operation,render_pass,clear_value:srgb:*'>
@ -296,7 +300,7 @@
<meta name=variant content='?q=webgpu:api,validation,buffer,mapping:gc_behavior,mappedAtCreation:*'> <meta name=variant content='?q=webgpu:api,validation,buffer,mapping:gc_behavior,mappedAtCreation:*'>
<meta name=variant content='?q=webgpu:api,validation,buffer,mapping:gc_behavior,mapAsync:*'> <meta name=variant content='?q=webgpu:api,validation,buffer,mapping:gc_behavior,mapAsync:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,features,query_types:createQuerySet:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,features,query_types:createQuerySet:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,features,query_types:writeTimestamp:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,features,query_types:timestamp:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:texture_descriptor:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:texture_descriptor:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:texture_descriptor_view_formats:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:texture_descriptor_view_formats:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:texture_view_descriptor:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:texture_view_descriptor:*'>
@ -304,9 +308,11 @@
<meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:canvas_configuration_view_formats:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:canvas_configuration_view_formats:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:depth_stencil_state:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:depth_stencil_state:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:render_bundle_encoder_descriptor_depth_stencil_format:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:render_bundle_encoder_descriptor_depth_stencil_format:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,features,texture_formats:check_capability_guarantees:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindGroups:createPipelineLayout,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindGroups:createPipelineLayout,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindGroups:createPipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindGroups:createPipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindGroups:validate,maxBindGroupsPlusVertexBuffers:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:createBindGroupLayout,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:createBindGroupLayout,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:createPipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:createPipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:validate:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:validate:*'>
@ -321,10 +327,14 @@
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxColorAttachments:validate,kMaxColorAttachmentsToTest:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxColorAttachments:validate,kMaxColorAttachmentsToTest:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeInvocationsPerWorkgroup:createComputePipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeInvocationsPerWorkgroup:createComputePipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupSizeX:createComputePipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupSizeX:createComputePipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupSizeX:validate,maxComputeInvocationsPerWorkgroup:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupSizeY:createComputePipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupSizeY:createComputePipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupSizeY:validate,maxComputeInvocationsPerWorkgroup:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupSizeZ:createComputePipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupSizeZ:createComputePipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupSizeZ:validate,maxComputeInvocationsPerWorkgroup:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupStorageSize:createComputePipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupStorageSize:createComputePipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupsPerDimension:dispatchWorkgroups,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupsPerDimension:dispatchWorkgroups,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxComputeWorkgroupsPerDimension:validate:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxDynamicStorageBuffersPerPipelineLayout:createBindGroupLayout,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxDynamicStorageBuffersPerPipelineLayout:createBindGroupLayout,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxDynamicUniformBuffersPerPipelineLayout:createBindGroupLayout,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxDynamicUniformBuffersPerPipelineLayout:createBindGroupLayout,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxInterStageShaderComponents:createRenderPipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxInterStageShaderComponents:createRenderPipeline,at_over:*'>
@ -336,6 +346,7 @@
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxSamplersPerShaderStage:createPipelineLayout,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxSamplersPerShaderStage:createPipelineLayout,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxSamplersPerShaderStage:createPipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxSamplersPerShaderStage:createPipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxStorageBufferBindingSize:createBindGroup,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxStorageBufferBindingSize:createBindGroup,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxStorageBufferBindingSize:validate:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxStorageBufferBindingSize:validate,maxBufferSize:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxStorageBufferBindingSize:validate,maxBufferSize:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxStorageBuffersPerShaderStage:createBindGroupLayout,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxStorageBuffersPerShaderStage:createBindGroupLayout,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxStorageBuffersPerShaderStage:createPipelineLayout,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxStorageBuffersPerShaderStage:createPipelineLayout,at_over:*'>
@ -356,8 +367,10 @@
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxUniformBuffersPerShaderStage:createPipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxUniformBuffersPerShaderStage:createPipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexAttributes:createRenderPipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexAttributes:createRenderPipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexBufferArrayStride:createRenderPipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexBufferArrayStride:createRenderPipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexBufferArrayStride:validate:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexBuffers:createRenderPipeline,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexBuffers:createRenderPipeline,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexBuffers:setVertexBuffer,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexBuffers:setVertexBuffer,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,maxVertexBuffers:validate,maxBindGroupsPlusVertexBuffers:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,minStorageBufferOffsetAlignment:createBindGroup,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,minStorageBufferOffsetAlignment:createBindGroup,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,minStorageBufferOffsetAlignment:setBindGroup,at_over:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,minStorageBufferOffsetAlignment:setBindGroup,at_over:*'>
<meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,minStorageBufferOffsetAlignment:validate,powerOf2:*'> <meta name=variant content='?q=webgpu:api,validation,capability_checks,limits,minStorageBufferOffsetAlignment:validate,powerOf2:*'>
@ -540,7 +553,6 @@
<meta name=variant content='?q=webgpu:api,validation,encoding,createRenderBundleEncoder:attachment_state,empty_color_formats:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,createRenderBundleEncoder:attachment_state,empty_color_formats:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,createRenderBundleEncoder:valid_texture_formats:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,createRenderBundleEncoder:valid_texture_formats:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,createRenderBundleEncoder:depth_stencil_readonly:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,createRenderBundleEncoder:depth_stencil_readonly:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,createRenderBundleEncoder:depth_stencil_readonly_with_undefined_depth:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,encoder_open_state:non_pass_commands:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,encoder_open_state:non_pass_commands:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,encoder_open_state:render_pass_commands:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,encoder_open_state:render_pass_commands:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,encoder_open_state:render_bundle_commands:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,encoder_open_state:render_bundle_commands:*'>
@ -565,9 +577,9 @@
<meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:occlusion_query,query_type:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:occlusion_query,query_type:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:occlusion_query,invalid_query_set:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:occlusion_query,invalid_query_set:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:occlusion_query,query_index:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:occlusion_query,query_index:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:timestamp_query,query_type_and_index:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:writeTimestamp,query_type_and_index:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:timestamp_query,invalid_query_set:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:writeTimestamp,invalid_query_set:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:timestamp_query,device_mismatch:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,queries,general:writeTimestamp,device_mismatch:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,queries,resolveQuerySet:queryset_and_destination_buffer_state:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,queries,resolveQuerySet:queryset_and_destination_buffer_state:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,queries,resolveQuerySet:first_query_and_query_count:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,queries,resolveQuerySet:first_query_and_query_count:*'>
<meta name=variant content='?q=webgpu:api,validation,encoding,queries,resolveQuerySet:destination_buffer_usage:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,queries,resolveQuerySet:destination_buffer_usage:*'>
@ -651,7 +663,7 @@
<meta name=variant content='?q=webgpu:api,validation,queue,destroyed,buffer:setIndexBuffer:*'> <meta name=variant content='?q=webgpu:api,validation,queue,destroyed,buffer:setIndexBuffer:*'>
<meta name=variant content='?q=webgpu:api,validation,queue,destroyed,buffer:resolveQuerySet:*'> <meta name=variant content='?q=webgpu:api,validation,queue,destroyed,buffer:resolveQuerySet:*'>
<meta name=variant content='?q=webgpu:api,validation,queue,destroyed,query_set:beginOcclusionQuery:*'> <meta name=variant content='?q=webgpu:api,validation,queue,destroyed,query_set:beginOcclusionQuery:*'>
<meta name=variant content='?q=webgpu:api,validation,queue,destroyed,query_set:writeTimestamp:*'> <meta name=variant content='?q=webgpu:api,validation,queue,destroyed,query_set:timestamps:*'>
<meta name=variant content='?q=webgpu:api,validation,queue,destroyed,query_set:resolveQuerySet:*'> <meta name=variant content='?q=webgpu:api,validation,queue,destroyed,query_set:resolveQuerySet:*'>
<meta name=variant content='?q=webgpu:api,validation,queue,destroyed,texture:writeTexture:*'> <meta name=variant content='?q=webgpu:api,validation,queue,destroyed,texture:writeTexture:*'>
<meta name=variant content='?q=webgpu:api,validation,queue,destroyed,texture:copyTextureToTexture:*'> <meta name=variant content='?q=webgpu:api,validation,queue,destroyed,texture:copyTextureToTexture:*'>
@ -709,6 +721,8 @@
<meta name=variant content='?q=webgpu:api,validation,render_pass,render_pass_descriptor:occlusionQuerySet,query_set_type:*'> <meta name=variant content='?q=webgpu:api,validation,render_pass,render_pass_descriptor:occlusionQuerySet,query_set_type:*'>
<meta name=variant content='?q=webgpu:api,validation,render_pass,resolve:resolve_attachment:*'> <meta name=variant content='?q=webgpu:api,validation,render_pass,resolve:resolve_attachment:*'>
<meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:format:*'> <meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:format:*'>
<meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:depthCompare_optional:*'>
<meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:depthWriteEnabled_optional:*'>
<meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:depth_test:*'> <meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:depth_test:*'>
<meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:depth_write:*'> <meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:depth_write:*'>
<meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:depth_write,frag_depth:*'> <meta name=variant content='?q=webgpu:api,validation,render_pipeline,depth_stencil_state:depth_write,frag_depth:*'>
@ -798,6 +812,9 @@
<meta name=variant content='?q=webgpu:api,validation,shader_module,entry_point:compute:*'> <meta name=variant content='?q=webgpu:api,validation,shader_module,entry_point:compute:*'>
<meta name=variant content='?q=webgpu:api,validation,shader_module,entry_point:vertex:*'> <meta name=variant content='?q=webgpu:api,validation,shader_module,entry_point:vertex:*'>
<meta name=variant content='?q=webgpu:api,validation,shader_module,entry_point:fragment:*'> <meta name=variant content='?q=webgpu:api,validation,shader_module,entry_point:fragment:*'>
<meta name=variant content='?q=webgpu:api,validation,shader_module,entry_point:compute_undefined_entry_point_and_extra_stage:*'>
<meta name=variant content='?q=webgpu:api,validation,shader_module,entry_point:vertex_undefined_entry_point_and_extra_stage:*'>
<meta name=variant content='?q=webgpu:api,validation,shader_module,entry_point:fragment_undefined_entry_point_and_extra_stage:*'>
<meta name=variant content='?q=webgpu:api,validation,shader_module,overrides:id_conflict:*'> <meta name=variant content='?q=webgpu:api,validation,shader_module,overrides:id_conflict:*'>
<meta name=variant content='?q=webgpu:api,validation,shader_module,overrides:name_conflict:*'> <meta name=variant content='?q=webgpu:api,validation,shader_module,overrides:name_conflict:*'>
<meta name=variant content='?q=webgpu:api,validation,state,device_lost,destroy:createBuffer:*'> <meta name=variant content='?q=webgpu:api,validation,state,device_lost,destroy:createBuffer:*'>
@ -849,16 +866,22 @@
<meta name=variant content='?q=webgpu:api,validation,texture,rg11b10ufloat_renderable:begin_render_pass_msaa_and_resolve:*'> <meta name=variant content='?q=webgpu:api,validation,texture,rg11b10ufloat_renderable:begin_render_pass_msaa_and_resolve:*'>
<meta name=variant content='?q=webgpu:api,validation,texture,rg11b10ufloat_renderable:begin_render_bundle_encoder:*'> <meta name=variant content='?q=webgpu:api,validation,texture,rg11b10ufloat_renderable:begin_render_bundle_encoder:*'>
<meta name=variant content='?q=webgpu:api,validation,texture,rg11b10ufloat_renderable:create_render_pipeline:*'> <meta name=variant content='?q=webgpu:api,validation,texture,rg11b10ufloat_renderable:create_render_pipeline:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,createBindGroup:viewDimension_matches_textureBindingViewDimension:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,encoding,cmds,copyTextureToBuffer:compressed:*'> <meta name=variant content='?q=webgpu:compat,api,validation,encoding,cmds,copyTextureToBuffer:compressed:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,encoding,cmds,copyTextureToTexture:compressed:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,encoding,programmable,pipeline_bind_group_compat:twoDifferentTextureViews,render_pass,used:*'> <meta name=variant content='?q=webgpu:compat,api,validation,encoding,programmable,pipeline_bind_group_compat:twoDifferentTextureViews,render_pass,used:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,encoding,programmable,pipeline_bind_group_compat:twoDifferentTextureViews,render_pass,unused:*'> <meta name=variant content='?q=webgpu:compat,api,validation,encoding,programmable,pipeline_bind_group_compat:twoDifferentTextureViews,render_pass,unused:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,encoding,programmable,pipeline_bind_group_compat:twoDifferentTextureViews,compute_pass,used:*'> <meta name=variant content='?q=webgpu:compat,api,validation,encoding,programmable,pipeline_bind_group_compat:twoDifferentTextureViews,compute_pass,used:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,encoding,programmable,pipeline_bind_group_compat:twoDifferentTextureViews,compute_pass,unused:*'> <meta name=variant content='?q=webgpu:compat,api,validation,encoding,programmable,pipeline_bind_group_compat:twoDifferentTextureViews,compute_pass,unused:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,render_pipeline,fragment_state:colorState:*'> <meta name=variant content='?q=webgpu:compat,api,validation,render_pipeline,fragment_state:colorState:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,render_pipeline,shader_module:sample_mask:*'> <meta name=variant content='?q=webgpu:compat,api,validation,render_pipeline,shader_module:sample_mask:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,render_pipeline,shader_module:interpolate:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,render_pipeline,vertex_state:maxVertexAttributesVertexIndexInstanceIndex:*'> <meta name=variant content='?q=webgpu:compat,api,validation,render_pipeline,vertex_state:maxVertexAttributesVertexIndexInstanceIndex:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,texture,createTexture:unsupportedTextureFormats:*'> <meta name=variant content='?q=webgpu:compat,api,validation,texture,createTexture:unsupportedTextureFormats:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,texture,createTexture:unsupportedTextureViewFormats:*'> <meta name=variant content='?q=webgpu:compat,api,validation,texture,createTexture:unsupportedTextureViewFormats:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,texture,createTexture:invalidTextureBindingViewDimension:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,texture,createTexture:depthOrArrayLayers_incompatible_with_textureBindingViewDimension:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,texture,createTexture:format_reinterpretation:*'>
<meta name=variant content='?q=webgpu:compat,api,validation,texture,cubeArray:cube_array:*'> <meta name=variant content='?q=webgpu:compat,api,validation,texture,cubeArray:cube_array:*'>
<meta name=variant content='?q=webgpu:examples:test_name:*'> <meta name=variant content='?q=webgpu:examples:test_name:*'>
<meta name=variant content='?q=webgpu:examples:not_implemented_yet,without_plan:*'> <meta name=variant content='?q=webgpu:examples:not_implemented_yet,without_plan:*'>
@ -883,6 +906,9 @@
<meta name=variant content='?q=webgpu:idl,constants,flags:ColorWrite,values:*'> <meta name=variant content='?q=webgpu:idl,constants,flags:ColorWrite,values:*'>
<meta name=variant content='?q=webgpu:idl,constants,flags:ShaderStage,count:*'> <meta name=variant content='?q=webgpu:idl,constants,flags:ShaderStage,count:*'>
<meta name=variant content='?q=webgpu:idl,constants,flags:ShaderStage,values:*'> <meta name=variant content='?q=webgpu:idl,constants,flags:ShaderStage,values:*'>
<meta name=variant content='?q=webgpu:idl,constructable:gpu_errors:*'>
<meta name=variant content='?q=webgpu:idl,constructable:pipeline_errors:*'>
<meta name=variant content='?q=webgpu:idl,constructable:uncaptured_error_event:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_addition:scalar:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_addition:scalar:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_addition:vector:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_addition:vector:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_addition:vector_scalar:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_addition:vector_scalar:*'>
@ -893,12 +919,20 @@
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_comparison:less_equals:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_comparison:less_equals:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_comparison:greater_than:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_comparison:greater_than:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_comparison:greater_equals:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_comparison:greater_equals:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_division:scalar:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_division:vector:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_division:vector_scalar:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_division:scalar_vector:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_matrix_addition:matrix:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_matrix_addition:matrix:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_matrix_subtraction:matrix:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_matrix_subtraction:matrix:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_multiplication:scalar:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_multiplication:scalar:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_multiplication:vector:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_multiplication:vector:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_multiplication:vector_scalar:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_multiplication:vector_scalar:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_multiplication:scalar_vector:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_multiplication:scalar_vector:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_remainder:scalar:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_remainder:vector:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_remainder:vector_scalar:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_remainder:scalar_vector:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_subtraction:scalar:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_subtraction:scalar:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_subtraction:vector:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_subtraction:vector:*'>
<meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_subtraction:vector_scalar:*'> <meta name=variant content='?q=webgpu:shader,execution,expression,binary,af_subtraction:vector_scalar:*'>
@ -1611,6 +1645,7 @@
<meta name=variant content='?q=webgpu:shader,execution,flow_control,while:while_continue:*'> <meta name=variant content='?q=webgpu:shader,execution,flow_control,while:while_continue:*'>
<meta name=variant content='?q=webgpu:shader,execution,flow_control,while:while_nested_break:*'> <meta name=variant content='?q=webgpu:shader,execution,flow_control,while:while_nested_break:*'>
<meta name=variant content='?q=webgpu:shader,execution,flow_control,while:while_nested_continue:*'> <meta name=variant content='?q=webgpu:shader,execution,flow_control,while:while_nested_continue:*'>
<meta name=variant content='?q=webgpu:shader,execution,memory_model,adjacent:f16:*'>
<meta name=variant content='?q=webgpu:shader,execution,memory_model,atomicity:atomicity:*'> <meta name=variant content='?q=webgpu:shader,execution,memory_model,atomicity:atomicity:*'>
<meta name=variant content='?q=webgpu:shader,execution,memory_model,barrier:workgroup_barrier_store_load:*'> <meta name=variant content='?q=webgpu:shader,execution,memory_model,barrier:workgroup_barrier_store_load:*'>
<meta name=variant content='?q=webgpu:shader,execution,memory_model,barrier:workgroup_barrier_load_store:*'> <meta name=variant content='?q=webgpu:shader,execution,memory_model,barrier:workgroup_barrier_load_store:*'>
@ -1637,6 +1672,8 @@
<meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:*'> <meta name=variant content='?q=webgpu:shader,execution,robust_access:linear_memory:*'>
<meta name=variant content='?q=webgpu:shader,execution,robust_access_vertex:vertex_buffer_access:*'> <meta name=variant content='?q=webgpu:shader,execution,robust_access_vertex:vertex_buffer_access:*'>
<meta name=variant content='?q=webgpu:shader,execution,shader_io,compute_builtins:inputs:*'> <meta name=variant content='?q=webgpu:shader,execution,shader_io,compute_builtins:inputs:*'>
<meta name=variant content='?q=webgpu:shader,execution,shader_io,fragment_builtins:inputs,position:*'>
<meta name=variant content='?q=webgpu:shader,execution,shader_io,fragment_builtins:inputs,interStage:*'>
<meta name=variant content='?q=webgpu:shader,execution,shader_io,shared_structs:shared_with_buffer:*'> <meta name=variant content='?q=webgpu:shader,execution,shader_io,shared_structs:shared_with_buffer:*'>
<meta name=variant content='?q=webgpu:shader,execution,shader_io,shared_structs:shared_between_stages:*'> <meta name=variant content='?q=webgpu:shader,execution,shader_io,shared_structs:shared_between_stages:*'>
<meta name=variant content='?q=webgpu:shader,execution,shader_io,shared_structs:shared_with_non_entry_point_function:*'> <meta name=variant content='?q=webgpu:shader,execution,shader_io,shared_structs:shared_with_non_entry_point_function:*'>
@ -1710,6 +1747,7 @@
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,atanh:integer_argument:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,atanh:integer_argument:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,atomics:stage:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,atomics:stage:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,bitcast:bad_const_to_f32:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,bitcast:bad_const_to_f32:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,bitcast:bad_const_to_f16:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,bitcast:bad_type_constructible:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,bitcast:bad_type_constructible:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,bitcast:bad_type_nonconstructible:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,bitcast:bad_type_nonconstructible:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,bitcast:bad_to_vec3h:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,bitcast:bad_to_vec3h:*'>
@ -1725,6 +1763,14 @@
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,cosh:integer_argument:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,cosh:integer_argument:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,degrees:values:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,degrees:values:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,degrees:integer_argument:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,degrees:integer_argument:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,dot4I8Packed:unsupported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,dot4I8Packed:supported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,dot4I8Packed:bad_args:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,dot4I8Packed:must_use:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,dot4U8Packed:unsupported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,dot4U8Packed:supported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,dot4U8Packed:bad_args:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,dot4U8Packed:must_use:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,exp:values:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,exp:values:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,exp:integer_argument:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,exp:integer_argument:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,exp2:values:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,exp2:values:*'>
@ -1742,6 +1788,22 @@
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,log2:integer_argument:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,log2:integer_argument:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,modf:values:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,modf:values:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,modf:integer_argument:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,modf:integer_argument:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xI8:unsupported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xI8:supported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xI8:bad_args:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xI8:must_use:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xI8Clamp:unsupported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xI8Clamp:supported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xI8Clamp:bad_args:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xI8Clamp:must_use:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xU8:unsupported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xU8:supported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xU8:bad_args:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xU8:must_use:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xU8Clamp:unsupported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xU8Clamp:supported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xU8Clamp:bad_args:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,pack4xU8Clamp:must_use:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,radians:values:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,radians:values:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,radians:integer_argument:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,radians:integer_argument:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,round:values:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,round:values:*'>
@ -1758,6 +1820,14 @@
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,sqrt:integer_argument:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,sqrt:integer_argument:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,tan:values:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,tan:values:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,tan:integer_argument:*'> <meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,tan:integer_argument:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,unpack4xI8:unsupported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,unpack4xI8:supported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,unpack4xI8:bad_args:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,unpack4xI8:must_use:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,unpack4xU8:unsupported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,unpack4xU8:supported:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,unpack4xU8:bad_args:*'>
<meta name=variant content='?q=webgpu:shader,validation,expression,call,builtin,unpack4xU8:must_use:*'>
<meta name=variant content='?q=webgpu:shader,validation,functions,alias_analysis:two_pointers:*'> <meta name=variant content='?q=webgpu:shader,validation,functions,alias_analysis:two_pointers:*'>
<meta name=variant content='?q=webgpu:shader,validation,functions,alias_analysis:one_pointer_one_module_scope:*'> <meta name=variant content='?q=webgpu:shader,validation,functions,alias_analysis:one_pointer_one_module_scope:*'>
<meta name=variant content='?q=webgpu:shader,validation,functions,alias_analysis:subcalls:*'> <meta name=variant content='?q=webgpu:shader,validation,functions,alias_analysis:subcalls:*'>
@ -2005,7 +2075,6 @@
<meta name=variant content='?q=webgpu:web_platform,copyToTexture,image:copy_subrect_from_2D_Canvas:*'> <meta name=variant content='?q=webgpu:web_platform,copyToTexture,image:copy_subrect_from_2D_Canvas:*'>
<meta name=variant content='?q=webgpu:web_platform,copyToTexture,video:copy_from_video:*'> <meta name=variant content='?q=webgpu:web_platform,copyToTexture,video:copy_from_video:*'>
<meta name=variant content='?q=webgpu:web_platform,external_texture,video:importExternalTexture,sample:*'> <meta name=variant content='?q=webgpu:web_platform,external_texture,video:importExternalTexture,sample:*'>
<meta name=variant content='?q=webgpu:web_platform,external_texture,video:importExternalTexture,sampleWithRotationMetadata:*'>
<meta name=variant content='?q=webgpu:web_platform,external_texture,video:importExternalTexture,sampleWithVideoFrameWithVisibleRectParam:*'> <meta name=variant content='?q=webgpu:web_platform,external_texture,video:importExternalTexture,sampleWithVideoFrameWithVisibleRectParam:*'>
<meta name=variant content='?q=webgpu:web_platform,external_texture,video:importExternalTexture,compute:*'> <meta name=variant content='?q=webgpu:web_platform,external_texture,video:importExternalTexture,compute:*'>
<meta name=variant content='?q=webgpu:web_platform,worker,worker:worker:*'> <meta name=variant content='?q=webgpu:web_platform,worker,worker:worker:*'>

View file

@ -1,3 +1,470 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ export {}; **/ /**
* A typed array of 16-bit float values. The contents are initialized to 0. If the requested number
* of bytes could not be allocated an exception is raised.
*/
/**
* Returns `true` if the value is a Float16Array instance.
* @since v3.4.0
*/
/**
* Returns `true` if the value is a type of TypedArray instance that contains Float16Array.
* @since v3.6.0
*/
/**
* Gets the Float16 value at the specified byte offset from the start of the view. There is
* no alignment constraint; multi-byte values may be fetched from any offset.
* @param byteOffset The place in the buffer at which the value should be retrieved.
* @param littleEndian If false or undefined, a big-endian value should be read,
* otherwise a little-endian value should be read.
*/
/**
* Stores an Float16 value at the specified byte offset from the start of the view.
* @param byteOffset The place in the buffer at which the value should be set.
* @param value The value to set.
* @param littleEndian If false or undefined, a big-endian value should be written,
* otherwise a little-endian value should be written.
*/
/**
* Returns the nearest half-precision float representation of a number.
* @param x A numeric expression.
*/export {};

View file

@ -1,23 +1,25 @@
/** /**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ /*! @petamoriken/float16 v3.6.6 | MIT License - https://github.com/petamoriken/float16 */ const THIS_IS_NOT_AN_OBJECT = **/ /*! @petamoriken/float16 v3.6.6 | MIT License - https://github.com/petamoriken/float16 */const THIS_IS_NOT_AN_OBJECT = "This is not an object";
'This is not an object'; const THIS_IS_NOT_A_FLOAT16ARRAY_OBJECT = "This is not a Float16Array object";
const THIS_IS_NOT_A_FLOAT16ARRAY_OBJECT = 'This is not a Float16Array object';
const THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY = const THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY =
'This constructor is not a subclass of Float16Array'; "This constructor is not a subclass of Float16Array";
const THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT = const THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT =
'The constructor property value is not an object'; "The constructor property value is not an object";
const SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT = const SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT =
"Species constructor didn't return TypedArray object"; "Species constructor didn't return TypedArray object";
const DERIVED_CONSTRUCTOR_CREATED_TYPEDARRAY_OBJECT_WHICH_WAS_TOO_SMALL_LENGTH = const DERIVED_CONSTRUCTOR_CREATED_TYPEDARRAY_OBJECT_WHICH_WAS_TOO_SMALL_LENGTH =
'Derived constructor created TypedArray object which was too small length'; "Derived constructor created TypedArray object which was too small length";
const ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER = 'Attempting to access detached ArrayBuffer'; const ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER =
const CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT = 'Cannot convert undefined or null to object'; "Attempting to access detached ArrayBuffer";
const CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT =
"Cannot convert undefined or null to object";
const CANNOT_MIX_BIGINT_AND_OTHER_TYPES = const CANNOT_MIX_BIGINT_AND_OTHER_TYPES =
'Cannot mix BigInt and other types, use explicit conversions'; "Cannot mix BigInt and other types, use explicit conversions";
const ITERATOR_PROPERTY_IS_NOT_CALLABLE = '@@iterator property is not callable'; const ITERATOR_PROPERTY_IS_NOT_CALLABLE = "@@iterator property is not callable";
const REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE = 'Reduce of empty array with no initial value'; const REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE =
const OFFSET_IS_OUT_OF_BOUNDS = 'Offset is out of bounds'; "Reduce of empty array with no initial value";
const OFFSET_IS_OUT_OF_BOUNDS = "Offset is out of bounds";
function uncurryThis(target) { function uncurryThis(target) {
return (thisArg, ...args) => { return (thisArg, ...args) => {
@ -25,7 +27,12 @@ function uncurryThis(target) {
}; };
} }
function uncurryThisGetter(target, key) { function uncurryThisGetter(target, key) {
return uncurryThis(ReflectGetOwnPropertyDescriptor(target, key).get); return uncurryThis(
ReflectGetOwnPropertyDescriptor(
target,
key
).get
);
} }
const { const {
apply: ReflectApply, apply: ReflectApply,
@ -37,49 +44,57 @@ const {
has: ReflectHas, has: ReflectHas,
ownKeys: ReflectOwnKeys, ownKeys: ReflectOwnKeys,
set: ReflectSet, set: ReflectSet,
setPrototypeOf: ReflectSetPrototypeOf, setPrototypeOf: ReflectSetPrototypeOf
} = Reflect; } = Reflect;
const NativeProxy = Proxy; const NativeProxy = Proxy;
const { MAX_SAFE_INTEGER: MAX_SAFE_INTEGER, isFinite: NumberIsFinite, isNaN: NumberIsNaN } = Number; const {
MAX_SAFE_INTEGER: MAX_SAFE_INTEGER,
isFinite: NumberIsFinite,
isNaN: NumberIsNaN
} = Number;
const { const {
iterator: SymbolIterator, iterator: SymbolIterator,
species: SymbolSpecies, species: SymbolSpecies,
toStringTag: SymbolToStringTag, toStringTag: SymbolToStringTag,
for: SymbolFor, for: SymbolFor
} = Symbol; } = Symbol;
const NativeObject = Object; const NativeObject = Object;
const { const {
create: ObjectCreate, create: ObjectCreate,
defineProperty: ObjectDefineProperty, defineProperty: ObjectDefineProperty,
freeze: ObjectFreeze, freeze: ObjectFreeze,
is: ObjectIs, is: ObjectIs
} = NativeObject; } = NativeObject;
const ObjectPrototype = NativeObject.prototype; const ObjectPrototype = NativeObject.prototype;
const ObjectPrototype__lookupGetter__ = ObjectPrototype.__lookupGetter__ const ObjectPrototype__lookupGetter__ = ObjectPrototype.__lookupGetter__ ?
? uncurryThis(ObjectPrototype.__lookupGetter__) uncurryThis(ObjectPrototype.__lookupGetter__) :
: (object, key) => { (object, key) => {
if (object == null) { if (object == null) {
throw NativeTypeError(CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT); throw NativeTypeError(
CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
);
}
let target = NativeObject(object);
do {
const descriptor = ReflectGetOwnPropertyDescriptor(target, key);
if (descriptor !== undefined) {
if (ObjectHasOwn(descriptor, "get")) {
return descriptor.get;
} }
let target = NativeObject(object); return;
do { }
const descriptor = ReflectGetOwnPropertyDescriptor(target, key); } while ((target = ReflectGetPrototypeOf(target)) !== null);
if (descriptor !== undefined) { };
if (ObjectHasOwn(descriptor, 'get')) { const ObjectHasOwn = NativeObject.hasOwn ||
return descriptor.get; uncurryThis(ObjectPrototype.hasOwnProperty);
}
return;
}
} while ((target = ReflectGetPrototypeOf(target)) !== null);
};
const ObjectHasOwn = NativeObject.hasOwn || uncurryThis(ObjectPrototype.hasOwnProperty);
const NativeArray = Array; const NativeArray = Array;
const ArrayIsArray = NativeArray.isArray; const ArrayIsArray = NativeArray.isArray;
const ArrayPrototype = NativeArray.prototype; const ArrayPrototype = NativeArray.prototype;
const ArrayPrototypeJoin = uncurryThis(ArrayPrototype.join); const ArrayPrototypeJoin = uncurryThis(ArrayPrototype.join);
const ArrayPrototypePush = uncurryThis(ArrayPrototype.push); const ArrayPrototypePush = uncurryThis(ArrayPrototype.push);
const ArrayPrototypeToLocaleString = uncurryThis(ArrayPrototype.toLocaleString); const ArrayPrototypeToLocaleString = uncurryThis(
ArrayPrototype.toLocaleString
);
const NativeArrayPrototypeSymbolIterator = ArrayPrototype[SymbolIterator]; const NativeArrayPrototypeSymbolIterator = ArrayPrototype[SymbolIterator];
const ArrayPrototypeSymbolIterator = uncurryThis(NativeArrayPrototypeSymbolIterator); const ArrayPrototypeSymbolIterator = uncurryThis(NativeArrayPrototypeSymbolIterator);
const MathTrunc = Math.trunc; const MathTrunc = Math.trunc;
@ -87,40 +102,50 @@ const NativeArrayBuffer = ArrayBuffer;
const ArrayBufferIsView = NativeArrayBuffer.isView; const ArrayBufferIsView = NativeArrayBuffer.isView;
const ArrayBufferPrototype = NativeArrayBuffer.prototype; const ArrayBufferPrototype = NativeArrayBuffer.prototype;
const ArrayBufferPrototypeSlice = uncurryThis(ArrayBufferPrototype.slice); const ArrayBufferPrototypeSlice = uncurryThis(ArrayBufferPrototype.slice);
const ArrayBufferPrototypeGetByteLength = uncurryThisGetter(ArrayBufferPrototype, 'byteLength'); const ArrayBufferPrototypeGetByteLength = uncurryThisGetter(ArrayBufferPrototype, "byteLength");
const NativeSharedArrayBuffer = typeof SharedArrayBuffer !== 'undefined' ? SharedArrayBuffer : null; const NativeSharedArrayBuffer = typeof SharedArrayBuffer !== "undefined" ? SharedArrayBuffer : null;
const SharedArrayBufferPrototypeGetByteLength = const SharedArrayBufferPrototypeGetByteLength = NativeSharedArrayBuffer &&
NativeSharedArrayBuffer && uncurryThisGetter(NativeSharedArrayBuffer.prototype, 'byteLength'); uncurryThisGetter(NativeSharedArrayBuffer.prototype, "byteLength");
const TypedArray = ReflectGetPrototypeOf(Uint8Array); const TypedArray = ReflectGetPrototypeOf(Uint8Array);
const TypedArrayFrom = TypedArray.from; const TypedArrayFrom = TypedArray.from;
const TypedArrayPrototype = TypedArray.prototype; const TypedArrayPrototype = TypedArray.prototype;
const NativeTypedArrayPrototypeSymbolIterator = TypedArrayPrototype[SymbolIterator]; const NativeTypedArrayPrototypeSymbolIterator = TypedArrayPrototype[SymbolIterator];
const TypedArrayPrototypeKeys = uncurryThis(TypedArrayPrototype.keys); const TypedArrayPrototypeKeys = uncurryThis(TypedArrayPrototype.keys);
const TypedArrayPrototypeValues = uncurryThis(TypedArrayPrototype.values); const TypedArrayPrototypeValues = uncurryThis(
TypedArrayPrototype.values
const TypedArrayPrototypeEntries = uncurryThis(TypedArrayPrototype.entries); );
const TypedArrayPrototypeEntries = uncurryThis(
TypedArrayPrototype.entries
);
const TypedArrayPrototypeSet = uncurryThis(TypedArrayPrototype.set); const TypedArrayPrototypeSet = uncurryThis(TypedArrayPrototype.set);
const TypedArrayPrototypeReverse = uncurryThis(TypedArrayPrototype.reverse); const TypedArrayPrototypeReverse = uncurryThis(
TypedArrayPrototype.reverse
);
const TypedArrayPrototypeFill = uncurryThis(TypedArrayPrototype.fill); const TypedArrayPrototypeFill = uncurryThis(TypedArrayPrototype.fill);
const TypedArrayPrototypeCopyWithin = uncurryThis(TypedArrayPrototype.copyWithin); const TypedArrayPrototypeCopyWithin = uncurryThis(
TypedArrayPrototype.copyWithin
);
const TypedArrayPrototypeSort = uncurryThis(TypedArrayPrototype.sort); const TypedArrayPrototypeSort = uncurryThis(TypedArrayPrototype.sort);
const TypedArrayPrototypeSlice = uncurryThis(TypedArrayPrototype.slice); const TypedArrayPrototypeSlice = uncurryThis(TypedArrayPrototype.slice);
const TypedArrayPrototypeSubarray = uncurryThis(TypedArrayPrototype.subarray); const TypedArrayPrototypeSubarray = uncurryThis(
TypedArrayPrototype.subarray
const TypedArrayPrototypeGetBuffer = uncurryThisGetter(TypedArrayPrototype, 'buffer'); );
const TypedArrayPrototypeGetBuffer = uncurryThisGetter(
const TypedArrayPrototypeGetByteOffset = uncurryThisGetter(TypedArrayPrototype, 'byteOffset'); TypedArrayPrototype,
"buffer"
const TypedArrayPrototypeGetLength = uncurryThisGetter(TypedArrayPrototype, 'length'); );
const TypedArrayPrototypeGetByteOffset = uncurryThisGetter(
TypedArrayPrototype,
"byteOffset"
);
const TypedArrayPrototypeGetLength = uncurryThisGetter(
TypedArrayPrototype,
"length"
);
const TypedArrayPrototypeGetSymbolToStringTag = uncurryThisGetter( const TypedArrayPrototypeGetSymbolToStringTag = uncurryThisGetter(
TypedArrayPrototype, TypedArrayPrototype,
SymbolToStringTag SymbolToStringTag
); );
const NativeUint16Array = Uint16Array; const NativeUint16Array = Uint16Array;
const Uint16ArrayFrom = (...args) => { const Uint16ArrayFrom = (...args) => {
return ReflectApply(TypedArrayFrom, NativeUint16Array, args); return ReflectApply(TypedArrayFrom, NativeUint16Array, args);
@ -129,13 +154,15 @@ const NativeUint32Array = Uint32Array;
const NativeFloat32Array = Float32Array; const NativeFloat32Array = Float32Array;
const ArrayIteratorPrototype = ReflectGetPrototypeOf([][SymbolIterator]()); const ArrayIteratorPrototype = ReflectGetPrototypeOf([][SymbolIterator]());
const ArrayIteratorPrototypeNext = uncurryThis(ArrayIteratorPrototype.next); const ArrayIteratorPrototypeNext = uncurryThis(ArrayIteratorPrototype.next);
const GeneratorPrototypeNext = uncurryThis((function* () {})().next); const GeneratorPrototypeNext = uncurryThis(function* () {}().next);
const IteratorPrototype = ReflectGetPrototypeOf(ArrayIteratorPrototype); const IteratorPrototype = ReflectGetPrototypeOf(ArrayIteratorPrototype);
const DataViewPrototype = DataView.prototype; const DataViewPrototype = DataView.prototype;
const DataViewPrototypeGetUint16 = uncurryThis(DataViewPrototype.getUint16); const DataViewPrototypeGetUint16 = uncurryThis(
DataViewPrototype.getUint16
const DataViewPrototypeSetUint16 = uncurryThis(DataViewPrototype.setUint16); );
const DataViewPrototypeSetUint16 = uncurryThis(
DataViewPrototype.setUint16
);
const NativeTypeError = TypeError; const NativeTypeError = TypeError;
const NativeRangeError = RangeError; const NativeRangeError = RangeError;
const NativeWeakSet = WeakSet; const NativeWeakSet = WeakSet;
@ -154,13 +181,13 @@ const SafeIteratorPrototype = ObjectCreate(null, {
value: function next() { value: function next() {
const arrayIterator = WeakMapPrototypeGet(arrayIterators, this); const arrayIterator = WeakMapPrototypeGet(arrayIterators, this);
return ArrayIteratorPrototypeNext(arrayIterator); return ArrayIteratorPrototypeNext(arrayIterator);
}, }
}, },
[SymbolIterator]: { [SymbolIterator]: {
value: function values() { value: function values() {
return this; return this;
}, }
}, }
}); });
function safeIfNeeded(array) { function safeIfNeeded(array) {
if (array[SymbolIterator] === NativeArrayPrototypeSymbolIterator) { if (array[SymbolIterator] === NativeArrayPrototypeSymbolIterator) {
@ -178,18 +205,14 @@ const DummyArrayIteratorPrototype = ObjectCreate(IteratorPrototype, {
return GeneratorPrototypeNext(generator); return GeneratorPrototypeNext(generator);
}, },
writable: true, writable: true,
configurable: true, configurable: true
}, }
}); });
for (const key of ReflectOwnKeys(ArrayIteratorPrototype)) { for (const key of ReflectOwnKeys(ArrayIteratorPrototype)) {
if (key === 'next') { if (key === "next") {
continue; continue;
} }
ObjectDefineProperty( ObjectDefineProperty(DummyArrayIteratorPrototype, key, ReflectGetOwnPropertyDescriptor(ArrayIteratorPrototype, key));
DummyArrayIteratorPrototype,
key,
ReflectGetOwnPropertyDescriptor(ArrayIteratorPrototype, key)
);
} }
function wrap(generator) { function wrap(generator) {
const dummy = ObjectCreate(DummyArrayIteratorPrototype); const dummy = ObjectCreate(DummyArrayIteratorPrototype);
@ -198,17 +221,19 @@ function wrap(generator) {
} }
function isObject(value) { function isObject(value) {
return (value !== null && typeof value === 'object') || typeof value === 'function'; return value !== null && typeof value === "object" ||
typeof value === "function";
} }
function isObjectLike(value) { function isObjectLike(value) {
return value !== null && typeof value === 'object'; return value !== null && typeof value === "object";
} }
function isNativeTypedArray(value) { function isNativeTypedArray(value) {
return TypedArrayPrototypeGetSymbolToStringTag(value) !== undefined; return TypedArrayPrototypeGetSymbolToStringTag(value) !== undefined;
} }
function isNativeBigIntTypedArray(value) { function isNativeBigIntTypedArray(value) {
const typedArrayName = TypedArrayPrototypeGetSymbolToStringTag(value); const typedArrayName = TypedArrayPrototypeGetSymbolToStringTag(value);
return typedArrayName === 'BigInt64Array' || typedArrayName === 'BigUint64Array'; return typedArrayName === "BigInt64Array" ||
typedArrayName === "BigUint64Array";
} }
function isArrayBuffer(value) { function isArrayBuffer(value) {
try { try {
@ -237,7 +262,7 @@ function isOrdinaryArray(value) {
return true; return true;
} }
const iterator = value[SymbolIterator](); const iterator = value[SymbolIterator]();
return iterator[SymbolToStringTag] === 'Array Iterator'; return iterator[SymbolToStringTag] === "Array Iterator";
} }
function isOrdinaryNativeTypedArray(value) { function isOrdinaryNativeTypedArray(value) {
if (!isNativeTypedArray(value)) { if (!isNativeTypedArray(value)) {
@ -247,14 +272,14 @@ function isOrdinaryNativeTypedArray(value) {
return true; return true;
} }
const iterator = value[SymbolIterator](); const iterator = value[SymbolIterator]();
return iterator[SymbolToStringTag] === 'Array Iterator'; return iterator[SymbolToStringTag] === "Array Iterator";
} }
function isCanonicalIntegerIndexString(value) { function isCanonicalIntegerIndexString(value) {
if (typeof value !== 'string') { if (typeof value !== "string") {
return false; return false;
} }
const number = +value; const number = +value;
if (value !== number + '') { if (value !== number + "") {
return false; return false;
} }
if (!NumberIsFinite(number)) { if (!NumberIsFinite(number)) {
@ -263,7 +288,7 @@ function isCanonicalIntegerIndexString(value) {
return number === MathTrunc(number); return number === MathTrunc(number);
} }
const brand = SymbolFor('__Float16Array__'); const brand = SymbolFor("__Float16Array__");
function hasFloat16ArrayBrand(target) { function hasFloat16ArrayBrand(target) {
if (!isObjectLike(target)) { if (!isObjectLike(target)) {
return false; return false;
@ -295,13 +320,13 @@ for (let i = 0; i < 256; ++i) {
shiftTable[i] = 24; shiftTable[i] = 24;
shiftTable[i | 0x100] = 24; shiftTable[i | 0x100] = 24;
} else if (e < -14) { } else if (e < -14) {
baseTable[i] = 0x0400 >> (-e - 14); baseTable[i] = 0x0400 >> -e - 14;
baseTable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000; baseTable[i | 0x100] = 0x0400 >> -e - 14 | 0x8000;
shiftTable[i] = -e - 1; shiftTable[i] = -e - 1;
shiftTable[i | 0x100] = -e - 1; shiftTable[i | 0x100] = -e - 1;
} else if (e <= 15) { } else if (e <= 15) {
baseTable[i] = (e + 15) << 10; baseTable[i] = e + 15 << 10;
baseTable[i | 0x100] = ((e + 15) << 10) | 0x8000; baseTable[i | 0x100] = e + 15 << 10 | 0x8000;
shiftTable[i] = 13; shiftTable[i] = 13;
shiftTable[i | 0x100] = 13; shiftTable[i | 0x100] = 13;
} else if (e < 128) { } else if (e < 128) {
@ -319,7 +344,7 @@ for (let i = 0; i < 256; ++i) {
function roundToFloat16Bits(num) { function roundToFloat16Bits(num) {
floatView[0] = num; floatView[0] = num;
const f = uint32View[0]; const f = uint32View[0];
const e = (f >> 23) & 0x1ff; const e = f >> 23 & 0x1ff;
return baseTable[e] + ((f & 0x007fffff) >> shiftTable[e]); return baseTable[e] + ((f & 0x007fffff) >> shiftTable[e]);
} }
const mantissaTable = new NativeUint32Array(2048); const mantissaTable = new NativeUint32Array(2048);
@ -337,7 +362,7 @@ for (let i = 1; i < 1024; ++i) {
mantissaTable[i] = m | e; mantissaTable[i] = m | e;
} }
for (let i = 1024; i < 2048; ++i) { for (let i = 1024; i < 2048; ++i) {
mantissaTable[i] = 0x38000000 + ((i - 1024) << 13); mantissaTable[i] = 0x38000000 + (i - 1024 << 13);
} }
for (let i = 1; i < 31; ++i) { for (let i = 1; i < 31; ++i) {
exponentTable[i] = i << 23; exponentTable[i] = i << 23;
@ -345,7 +370,7 @@ for (let i = 1; i < 31; ++i) {
exponentTable[31] = 0x47800000; exponentTable[31] = 0x47800000;
exponentTable[32] = 0x80000000; exponentTable[32] = 0x80000000;
for (let i = 33; i < 63; ++i) { for (let i = 33; i < 63; ++i) {
exponentTable[i] = 0x80000000 + ((i - 32) << 23); exponentTable[i] = 0x80000000 + (i - 32 << 23);
} }
exponentTable[63] = 0xc7800000; exponentTable[63] = 0xc7800000;
for (let i = 1; i < 64; ++i) { for (let i = 1; i < 64; ++i) {
@ -371,7 +396,9 @@ function ToLength(target) {
if (length < 0) { if (length < 0) {
return 0; return 0;
} }
return length < MAX_SAFE_INTEGER ? length : MAX_SAFE_INTEGER; return length < MAX_SAFE_INTEGER ?
length :
MAX_SAFE_INTEGER;
} }
function SpeciesConstructor(target, defaultConstructor) { function SpeciesConstructor(target, defaultConstructor) {
if (!isObject(target)) { if (!isObject(target)) {
@ -434,10 +461,8 @@ function defaultCompare(x, y) {
const BYTES_PER_ELEMENT = 2; const BYTES_PER_ELEMENT = 2;
const float16bitsArrays = new NativeWeakMap(); const float16bitsArrays = new NativeWeakMap();
function isFloat16Array(target) { function isFloat16Array(target) {
return ( return WeakMapPrototypeHas(float16bitsArrays, target) ||
WeakMapPrototypeHas(float16bitsArrays, target) || !ArrayBufferIsView(target) && hasFloat16ArrayBrand(target);
(!ArrayBufferIsView(target) && hasFloat16ArrayBrand(target))
);
} }
function assertFloat16Array(target) { function assertFloat16Array(target) {
if (!isFloat16Array(target)) { if (!isFloat16Array(target)) {
@ -450,7 +475,7 @@ function assertSpeciesTypedArray(target, count) {
if (!isTargetFloat16Array && !isTargetTypedArray) { if (!isTargetFloat16Array && !isTargetTypedArray) {
throw NativeTypeError(SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT); throw NativeTypeError(SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT);
} }
if (typeof count === 'number') { if (typeof count === "number") {
let length; let length;
if (isTargetFloat16Array) { if (isTargetFloat16Array) {
const float16bitsArray = getFloat16BitsArray(target); const float16bitsArray = getFloat16BitsArray(target);
@ -481,11 +506,11 @@ function getFloat16BitsArray(float16) {
if (IsDetachedBuffer(buffer)) { if (IsDetachedBuffer(buffer)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER); throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
} }
const cloned = ReflectConstruct( const cloned = ReflectConstruct(Float16Array, [
Float16Array, buffer,
[buffer, float16.byteOffset, float16.length], float16.byteOffset,
float16.constructor float16.length],
); float16.constructor);
return WeakMapPrototypeGet(float16bitsArrays, cloned); return WeakMapPrototypeGet(float16bitsArrays, cloned);
} }
function copyToArray(float16bitsArray) { function copyToArray(float16bitsArray) {
@ -502,7 +527,7 @@ for (const key of ReflectOwnKeys(TypedArrayPrototype)) {
continue; continue;
} }
const descriptor = ReflectGetOwnPropertyDescriptor(TypedArrayPrototype, key); const descriptor = ReflectGetOwnPropertyDescriptor(TypedArrayPrototype, key);
if (ObjectHasOwn(descriptor, 'get') && typeof descriptor.get === 'function') { if (ObjectHasOwn(descriptor, "get") && typeof descriptor.get === "function") {
WeakSetPrototypeAdd(TypedArrayPrototypeGetters, descriptor.get); WeakSetPrototypeAdd(TypedArrayPrototypeGetters, descriptor.get);
} }
} }
@ -511,9 +536,7 @@ const handler = ObjectFreeze({
if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) { if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
return convertToNumber(ReflectGet(target, key)); return convertToNumber(ReflectGet(target, key));
} }
if ( if (WeakSetPrototypeHas(TypedArrayPrototypeGetters, ObjectPrototype__lookupGetter__(target, key))) {
WeakSetPrototypeHas(TypedArrayPrototypeGetters, ObjectPrototype__lookupGetter__(target, key))
) {
return ReflectGet(target, key); return ReflectGet(target, key);
} }
return ReflectGet(target, key, receiver); return ReflectGet(target, key, receiver);
@ -534,25 +557,21 @@ const handler = ObjectFreeze({
}, },
defineProperty(target, key, descriptor) { defineProperty(target, key, descriptor) {
if ( if (
isCanonicalIntegerIndexString(key) && isCanonicalIntegerIndexString(key) &&
ObjectHasOwn(target, key) && ObjectHasOwn(target, key) &&
ObjectHasOwn(descriptor, 'value') ObjectHasOwn(descriptor, "value"))
) { {
descriptor.value = roundToFloat16Bits(descriptor.value); descriptor.value = roundToFloat16Bits(descriptor.value);
return ReflectDefineProperty(target, key, descriptor); return ReflectDefineProperty(target, key, descriptor);
} }
return ReflectDefineProperty(target, key, descriptor); return ReflectDefineProperty(target, key, descriptor);
}, }
}); });
class Float16Array { class Float16Array {
constructor(input, _byteOffset, _length) { constructor(input, _byteOffset, _length) {
let float16bitsArray; let float16bitsArray;
if (isFloat16Array(input)) { if (isFloat16Array(input)) {
float16bitsArray = ReflectConstruct( float16bitsArray = ReflectConstruct(NativeUint16Array, [getFloat16BitsArray(input)], new.target);
NativeUint16Array,
[getFloat16BitsArray(input)],
new.target
);
} else if (isObject(input) && !isArrayBuffer(input)) { } else if (isObject(input) && !isArrayBuffer(input)) {
let list; let list;
let length; let length;
@ -560,21 +579,25 @@ class Float16Array {
list = input; list = input;
length = TypedArrayPrototypeGetLength(input); length = TypedArrayPrototypeGetLength(input);
const buffer = TypedArrayPrototypeGetBuffer(input); const buffer = TypedArrayPrototypeGetBuffer(input);
const BufferConstructor = !isSharedArrayBuffer(buffer) const BufferConstructor = !isSharedArrayBuffer(buffer) ?
? SpeciesConstructor(buffer, NativeArrayBuffer) SpeciesConstructor(
: NativeArrayBuffer; buffer,
NativeArrayBuffer
) :
NativeArrayBuffer;
if (IsDetachedBuffer(buffer)) { if (IsDetachedBuffer(buffer)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER); throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
} }
if (isNativeBigIntTypedArray(input)) { if (isNativeBigIntTypedArray(input)) {
throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES); throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES);
} }
const data = new BufferConstructor(length * BYTES_PER_ELEMENT); const data = new BufferConstructor(
length * BYTES_PER_ELEMENT
);
float16bitsArray = ReflectConstruct(NativeUint16Array, [data], new.target); float16bitsArray = ReflectConstruct(NativeUint16Array, [data], new.target);
} else { } else {
const iterator = input[SymbolIterator]; const iterator = input[SymbolIterator];
if (iterator != null && typeof iterator !== 'function') { if (iterator != null && typeof iterator !== "function") {
throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE); throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE);
} }
if (iterator != null) { if (iterator != null) {
@ -604,7 +627,9 @@ class Float16Array {
static from(src, ...opts) { static from(src, ...opts) {
const Constructor = this; const Constructor = this;
if (!ReflectHas(Constructor, brand)) { if (!ReflectHas(Constructor, brand)) {
throw NativeTypeError(THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY); throw NativeTypeError(
THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY
);
} }
if (Constructor === Float16Array) { if (Constructor === Float16Array) {
if (isFloat16Array(src) && opts.length === 0) { if (isFloat16Array(src) && opts.length === 0) {
@ -614,32 +639,33 @@ class Float16Array {
TypedArrayPrototypeGetByteOffset(float16bitsArray), TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray) TypedArrayPrototypeGetLength(float16bitsArray)
); );
return new Float16Array(
return new Float16Array(TypedArrayPrototypeGetBuffer(TypedArrayPrototypeSlice(uint16))); TypedArrayPrototypeGetBuffer(TypedArrayPrototypeSlice(uint16))
);
} }
if (opts.length === 0) { if (opts.length === 0) {
return new Float16Array( return new Float16Array(
TypedArrayPrototypeGetBuffer(Uint16ArrayFrom(src, roundToFloat16Bits)) TypedArrayPrototypeGetBuffer(
Uint16ArrayFrom(src, roundToFloat16Bits)
)
); );
} }
const mapFunc = opts[0]; const mapFunc = opts[0];
const thisArg = opts[1]; const thisArg = opts[1];
return new Float16Array( return new Float16Array(
TypedArrayPrototypeGetBuffer( TypedArrayPrototypeGetBuffer(
Uint16ArrayFrom( Uint16ArrayFrom(src, function (val, ...args) {
src, return roundToFloat16Bits(
function (val, ...args) { ReflectApply(mapFunc, this, [val, ...safeIfNeeded(args)])
return roundToFloat16Bits(ReflectApply(mapFunc, this, [val, ...safeIfNeeded(args)])); );
}, }, thisArg)
thisArg
)
) )
); );
} }
let list; let list;
let length; let length;
const iterator = src[SymbolIterator]; const iterator = src[SymbolIterator];
if (iterator != null && typeof iterator !== 'function') { if (iterator != null && typeof iterator !== "function") {
throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE); throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE);
} }
if (iterator != null) { if (iterator != null) {
@ -655,7 +681,9 @@ class Float16Array {
} }
} else { } else {
if (src == null) { if (src == null) {
throw NativeTypeError(CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT); throw NativeTypeError(
CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
);
} }
list = NativeObject(src); list = NativeObject(src);
length = ToLength(list.length); length = ToLength(list.length);
@ -677,7 +705,9 @@ class Float16Array {
static of(...items) { static of(...items) {
const Constructor = this; const Constructor = this;
if (!ReflectHas(Constructor, brand)) { if (!ReflectHas(Constructor, brand)) {
throw NativeTypeError(THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY); throw NativeTypeError(
THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY
);
} }
const length = items.length; const length = items.length;
if (Constructor === Float16Array) { if (Constructor === Float16Array) {
@ -702,24 +732,20 @@ class Float16Array {
values() { values() {
assertFloat16Array(this); assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this); const float16bitsArray = getFloat16BitsArray(this);
return wrap( return wrap(function* () {
(function* () { for (const val of TypedArrayPrototypeValues(float16bitsArray)) {
for (const val of TypedArrayPrototypeValues(float16bitsArray)) { yield convertToNumber(val);
yield convertToNumber(val); }
} }());
})()
);
} }
entries() { entries() {
assertFloat16Array(this); assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this); const float16bitsArray = getFloat16BitsArray(this);
return wrap( return wrap(function* () {
(function* () { for (const [i, val] of TypedArrayPrototypeEntries(float16bitsArray)) {
for (const [i, val] of TypedArrayPrototypeEntries(float16bitsArray)) { yield [i, convertToNumber(val)];
yield [i, convertToNumber(val)]; }
} }());
})()
);
} }
at(index) { at(index) {
assertFloat16Array(this); assertFloat16Array(this);
@ -743,7 +769,9 @@ class Float16Array {
const array = getFloat16BitsArray(proxy); const array = getFloat16BitsArray(proxy);
for (let i = 0; i < length; ++i) { for (let i = 0; i < length; ++i) {
const val = convertToNumber(float16bitsArray[i]); const val = convertToNumber(float16bitsArray[i]);
array[i] = roundToFloat16Bits(ReflectApply(callback, thisArg, [val, i, this])); array[i] = roundToFloat16Bits(
ReflectApply(callback, thisArg, [val, i, this])
);
} }
return proxy; return proxy;
} }
@ -788,7 +816,12 @@ class Float16Array {
start = 0; start = 0;
} }
for (let i = start; i < length; ++i) { for (let i = start; i < length; ++i) {
accumulator = callback(accumulator, convertToNumber(float16bitsArray[i]), i, this); accumulator = callback(
accumulator,
convertToNumber(float16bitsArray[i]),
i,
this
);
} }
return accumulator; return accumulator;
} }
@ -808,7 +841,12 @@ class Float16Array {
start = length - 1; start = length - 1;
} }
for (let i = start; i >= 0; --i) { for (let i = start; i >= 0; --i) {
accumulator = callback(accumulator, convertToNumber(float16bitsArray[i]), i, this); accumulator = callback(
accumulator,
convertToNumber(float16bitsArray[i]),
i,
this
);
} }
return accumulator; return accumulator;
} }
@ -818,7 +856,11 @@ class Float16Array {
const length = TypedArrayPrototypeGetLength(float16bitsArray); const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0]; const thisArg = opts[0];
for (let i = 0; i < length; ++i) { for (let i = 0; i < length; ++i) {
ReflectApply(callback, thisArg, [convertToNumber(float16bitsArray[i]), i, this]); ReflectApply(callback, thisArg, [
convertToNumber(float16bitsArray[i]),
i,
this]
);
} }
} }
find(callback, ...opts) { find(callback, ...opts) {
@ -877,7 +919,13 @@ class Float16Array {
const length = TypedArrayPrototypeGetLength(float16bitsArray); const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0]; const thisArg = opts[0];
for (let i = 0; i < length; ++i) { for (let i = 0; i < length; ++i) {
if (!ReflectApply(callback, thisArg, [convertToNumber(float16bitsArray[i]), i, this])) { if (
!ReflectApply(callback, thisArg, [
convertToNumber(float16bitsArray[i]),
i,
this]
))
{
return false; return false;
} }
} }
@ -889,7 +937,13 @@ class Float16Array {
const length = TypedArrayPrototypeGetLength(float16bitsArray); const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0]; const thisArg = opts[0];
for (let i = 0; i < length; ++i) { for (let i = 0; i < length; ++i) {
if (ReflectApply(callback, thisArg, [convertToNumber(float16bitsArray[i]), i, this])) { if (
ReflectApply(callback, thisArg, [
convertToNumber(float16bitsArray[i]),
i,
this]
))
{
return true; return true;
} }
} }
@ -903,10 +957,14 @@ class Float16Array {
throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS); throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
} }
if (input == null) { if (input == null) {
throw NativeTypeError(CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT); throw NativeTypeError(
CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
);
} }
if (isNativeBigIntTypedArray(input)) { if (isNativeBigIntTypedArray(input)) {
throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES); throw NativeTypeError(
CANNOT_MIX_BIGINT_AND_OTHER_TYPES
);
} }
if (isFloat16Array(input)) { if (isFloat16Array(input)) {
return TypedArrayPrototypeSet( return TypedArrayPrototypeSet(
@ -940,8 +998,11 @@ class Float16Array {
fill(value, ...opts) { fill(value, ...opts) {
assertFloat16Array(this); assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this); const float16bitsArray = getFloat16BitsArray(this);
TypedArrayPrototypeFill(float16bitsArray, roundToFloat16Bits(value), ...safeIfNeeded(opts)); TypedArrayPrototypeFill(
float16bitsArray,
roundToFloat16Bits(value),
...safeIfNeeded(opts)
);
return this; return this;
} }
copyWithin(target, start, ...opts) { copyWithin(target, start, ...opts) {
@ -969,9 +1030,10 @@ class Float16Array {
TypedArrayPrototypeGetByteOffset(float16bitsArray), TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray) TypedArrayPrototypeGetLength(float16bitsArray)
); );
return new Float16Array( return new Float16Array(
TypedArrayPrototypeGetBuffer(TypedArrayPrototypeSlice(uint16, start, end)) TypedArrayPrototypeGetBuffer(
TypedArrayPrototypeSlice(uint16, start, end)
)
); );
} }
const length = TypedArrayPrototypeGetLength(float16bitsArray); const length = TypedArrayPrototypeGetLength(float16bitsArray);
@ -1020,14 +1082,12 @@ class Float16Array {
TypedArrayPrototypeGetByteOffset(float16bitsArray), TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray) TypedArrayPrototypeGetLength(float16bitsArray)
); );
const uint16Subarray = TypedArrayPrototypeSubarray(uint16, begin, end); const uint16Subarray = TypedArrayPrototypeSubarray(uint16, begin, end);
const array = new Constructor( const array = new Constructor(
TypedArrayPrototypeGetBuffer(uint16Subarray), TypedArrayPrototypeGetBuffer(uint16Subarray),
TypedArrayPrototypeGetByteOffset(uint16Subarray), TypedArrayPrototypeGetByteOffset(uint16Subarray),
TypedArrayPrototypeGetLength(uint16Subarray) TypedArrayPrototypeGetLength(uint16Subarray)
); );
assertSpeciesTypedArray(array); assertSpeciesTypedArray(array);
return array; return array;
} }
@ -1046,7 +1106,10 @@ class Float16Array {
} }
} }
for (let i = from; i < length; ++i) { for (let i = from; i < length; ++i) {
if (ObjectHasOwn(float16bitsArray, i) && convertToNumber(float16bitsArray[i]) === element) { if (
ObjectHasOwn(float16bitsArray, i) &&
convertToNumber(float16bitsArray[i]) === element)
{
return i; return i;
} }
} }
@ -1066,7 +1129,10 @@ class Float16Array {
from += length; from += length;
} }
for (let i = from; i >= 0; --i) { for (let i = from; i >= 0; --i) {
if (ObjectHasOwn(float16bitsArray, i) && convertToNumber(float16bitsArray[i]) === element) { if (
ObjectHasOwn(float16bitsArray, i) &&
convertToNumber(float16bitsArray[i]) === element)
{
return i; return i;
} }
} }
@ -1112,23 +1178,23 @@ class Float16Array {
} }
get [SymbolToStringTag]() { get [SymbolToStringTag]() {
if (isFloat16Array(this)) { if (isFloat16Array(this)) {
return 'Float16Array'; return "Float16Array";
} }
} }
} }
ObjectDefineProperty(Float16Array, 'BYTES_PER_ELEMENT', { ObjectDefineProperty(Float16Array, "BYTES_PER_ELEMENT", {
value: BYTES_PER_ELEMENT, value: BYTES_PER_ELEMENT
}); });
ObjectDefineProperty(Float16Array, brand, {}); ObjectDefineProperty(Float16Array, brand, {});
ReflectSetPrototypeOf(Float16Array, TypedArray); ReflectSetPrototypeOf(Float16Array, TypedArray);
const Float16ArrayPrototype = Float16Array.prototype; const Float16ArrayPrototype = Float16Array.prototype;
ObjectDefineProperty(Float16ArrayPrototype, 'BYTES_PER_ELEMENT', { ObjectDefineProperty(Float16ArrayPrototype, "BYTES_PER_ELEMENT", {
value: BYTES_PER_ELEMENT, value: BYTES_PER_ELEMENT
}); });
ObjectDefineProperty(Float16ArrayPrototype, SymbolIterator, { ObjectDefineProperty(Float16ArrayPrototype, SymbolIterator, {
value: Float16ArrayPrototype.values, value: Float16ArrayPrototype.values,
writable: true, writable: true,
configurable: true, configurable: true
}); });
ReflectSetPrototypeOf(Float16ArrayPrototype, TypedArrayPrototype); ReflectSetPrototypeOf(Float16ArrayPrototype, TypedArrayPrototype);
@ -1137,7 +1203,9 @@ function isTypedArray(target) {
} }
function getFloat16(dataView, byteOffset, ...opts) { function getFloat16(dataView, byteOffset, ...opts) {
return convertToNumber(DataViewPrototypeGetUint16(dataView, byteOffset, ...safeIfNeeded(opts))); return convertToNumber(
DataViewPrototypeGetUint16(dataView, byteOffset, ...safeIfNeeded(opts))
);
} }
function setFloat16(dataView, byteOffset, value, ...opts) { function setFloat16(dataView, byteOffset, value, ...opts) {
return DataViewPrototypeSetUint16( return DataViewPrototypeSetUint16(

View file

@ -0,0 +1,106 @@
{
"webgpu/shader/execution/binary/af_addition.bin": "345a28b7",
"webgpu/shader/execution/binary/af_logical.bin": "27321b9c",
"webgpu/shader/execution/binary/af_division.bin": "c87f1318",
"webgpu/shader/execution/binary/af_matrix_addition.bin": "69cc5319",
"webgpu/shader/execution/binary/af_matrix_subtraction.bin": "c1d89b26",
"webgpu/shader/execution/binary/af_multiplication.bin": "6c3abeab",
"webgpu/shader/execution/binary/af_remainder.bin": "8bd97400",
"webgpu/shader/execution/binary/af_subtraction.bin": "5a7112fa",
"webgpu/shader/execution/binary/f16_addition.bin": "479f0e78",
"webgpu/shader/execution/binary/f16_logical.bin": "431e624e",
"webgpu/shader/execution/binary/f16_division.bin": "9e3455fc",
"webgpu/shader/execution/binary/f16_matrix_addition.bin": "c0cf381b",
"webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "51edc282",
"webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "a612226e",
"webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "64491a9",
"webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "541863d2",
"webgpu/shader/execution/binary/f16_multiplication.bin": "1448ea2d",
"webgpu/shader/execution/binary/f16_remainder.bin": "cde237da",
"webgpu/shader/execution/binary/f16_subtraction.bin": "2739d887",
"webgpu/shader/execution/binary/f32_addition.bin": "f532fa83",
"webgpu/shader/execution/binary/f32_logical.bin": "ff723c9d",
"webgpu/shader/execution/binary/f32_division.bin": "1f9f3be2",
"webgpu/shader/execution/binary/f32_matrix_addition.bin": "68f190d7",
"webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "a126aaf1",
"webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "5fa08811",
"webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "d9270923",
"webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "9e508eda",
"webgpu/shader/execution/binary/f32_multiplication.bin": "acb51036",
"webgpu/shader/execution/binary/f32_remainder.bin": "26abf1b",
"webgpu/shader/execution/binary/f32_subtraction.bin": "1a895776",
"webgpu/shader/execution/binary/i32_arithmetic.bin": "ae1c1d58",
"webgpu/shader/execution/binary/i32_comparison.bin": "46155b50",
"webgpu/shader/execution/binary/u32_arithmetic.bin": "bab5328e",
"webgpu/shader/execution/binary/u32_comparison.bin": "34d818e3",
"webgpu/shader/execution/abs.bin": "ea7276ee",
"webgpu/shader/execution/acos.bin": "6532fe83",
"webgpu/shader/execution/acosh.bin": "3ccf99c0",
"webgpu/shader/execution/asin.bin": "e4ca1497",
"webgpu/shader/execution/asinh.bin": "a825fb5e",
"webgpu/shader/execution/atan.bin": "83d7b73a",
"webgpu/shader/execution/atan2.bin": "5dc6e553",
"webgpu/shader/execution/atanh.bin": "ff869593",
"webgpu/shader/execution/bitcast.bin": "692546d7",
"webgpu/shader/execution/ceil.bin": "dc82c7f0",
"webgpu/shader/execution/clamp.bin": "8a6b7591",
"webgpu/shader/execution/cos.bin": "37d594c9",
"webgpu/shader/execution/cosh.bin": "e7ef1519",
"webgpu/shader/execution/cross.bin": "ca40471f",
"webgpu/shader/execution/degrees.bin": "2194e1ab",
"webgpu/shader/execution/determinant.bin": "a1ef2144",
"webgpu/shader/execution/distance.bin": "77edf94",
"webgpu/shader/execution/dot.bin": "e8243a47",
"webgpu/shader/execution/exp.bin": "ed53aa3b",
"webgpu/shader/execution/exp2.bin": "f09ed3ed",
"webgpu/shader/execution/faceForward.bin": "ba3a56fb",
"webgpu/shader/execution/floor.bin": "ae0f3a23",
"webgpu/shader/execution/fma.bin": "1f259679",
"webgpu/shader/execution/fract.bin": "6d019f67",
"webgpu/shader/execution/frexp.bin": "cf521b43",
"webgpu/shader/execution/inverseSqrt.bin": "10006497",
"webgpu/shader/execution/ldexp.bin": "a34df4c9",
"webgpu/shader/execution/length.bin": "d8c6cccf",
"webgpu/shader/execution/log.bin": "fb232771",
"webgpu/shader/execution/log2.bin": "5e0540a0",
"webgpu/shader/execution/max.bin": "3dcb4df7",
"webgpu/shader/execution/min.bin": "c1eee2dc",
"webgpu/shader/execution/mix.bin": "ec107b2a",
"webgpu/shader/execution/modf.bin": "3657eaa7",
"webgpu/shader/execution/normalize.bin": "6c6c95cd",
"webgpu/shader/execution/pack2x16float.bin": "9c1bbb0",
"webgpu/shader/execution/pow.bin": "b016609a",
"webgpu/shader/execution/quantizeToF16.bin": "f35538e5",
"webgpu/shader/execution/radians.bin": "63180198",
"webgpu/shader/execution/reflect.bin": "fbd9afd8",
"webgpu/shader/execution/refract.bin": "bd496e20",
"webgpu/shader/execution/round.bin": "2a940af1",
"webgpu/shader/execution/saturate.bin": "31c4b685",
"webgpu/shader/execution/sign.bin": "f5de501b",
"webgpu/shader/execution/sin.bin": "18ff92f7",
"webgpu/shader/execution/sinh.bin": "b6b0fa4f",
"webgpu/shader/execution/smoothstep.bin": "ec4560e1",
"webgpu/shader/execution/sqrt.bin": "746a3e0c",
"webgpu/shader/execution/step.bin": "73253e0c",
"webgpu/shader/execution/tan.bin": "33b15959",
"webgpu/shader/execution/tanh.bin": "39e57783",
"webgpu/shader/execution/transpose.bin": "864aa27a",
"webgpu/shader/execution/trunc.bin": "5a0d2a2",
"webgpu/shader/execution/unpack2x16float.bin": "e882c632",
"webgpu/shader/execution/unpack2x16snorm.bin": "1b639761",
"webgpu/shader/execution/unpack2x16unorm.bin": "c491aba5",
"webgpu/shader/execution/unpack4x8snorm.bin": "f656b21e",
"webgpu/shader/execution/unpack4x8unorm.bin": "9fe4db5a",
"webgpu/shader/execution/unary/af_arithmetic.bin": "833e6033",
"webgpu/shader/execution/unary/af_assignment.bin": "c533f757",
"webgpu/shader/execution/unary/bool_conversion.bin": "2b501a16",
"webgpu/shader/execution/unary/f16_arithmetic.bin": "4ac2bee0",
"webgpu/shader/execution/unary/f16_conversion.bin": "ea17ab50",
"webgpu/shader/execution/unary/f32_arithmetic.bin": "8f702442",
"webgpu/shader/execution/unary/f32_conversion.bin": "23ae43b3",
"webgpu/shader/execution/unary/i32_arithmetic.bin": "8704047",
"webgpu/shader/execution/unary/i32_complement.bin": "7dec3502",
"webgpu/shader/execution/unary/i32_conversion.bin": "45acb16d",
"webgpu/shader/execution/unary/u32_complement.bin": "e000b062",
"webgpu/shader/execution/unary/u32_conversion.bin": "f2ffbc61"
}

Some files were not shown because too many files have changed in this diff Show more