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 {
format: convert_texture_format(dsf),
depth_read_only: descriptor.depthReadOnly, depth_read_only: descriptor.depthReadOnly,
stencil_read_only: descriptor.stencilReadOnly, 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 // First check the in-memory cache
let data = this.cache.get(cacheable.path); const node = this.cache.get(cacheable.path);
if (data !== undefined) { if (node !== undefined) {
this.log('in-memory cache hit'); this.log('in-memory cache hit');
return Promise.resolve(data); 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

@ -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.
* *
@ -141,8 +148,8 @@ export class Fixture {
'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

@ -2,6 +2,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');
const fs = require('fs'); const fs = require('fs');

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

@ -4,8 +4,7 @@
* 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

@ -2,10 +2,31 @@
* 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

@ -3,32 +3,86 @@
**/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

@ -2,6 +2,8 @@
* 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

@ -3,9 +3,12 @@
**/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 } = {}) {
@ -17,8 +20,8 @@ export class Logger {
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

@ -5,6 +5,20 @@
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

@ -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

@ -20,7 +20,7 @@ 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.
]); ]);
@ -30,10 +30,10 @@ const fromStringMagicValue = new Map([
[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(
@ -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');
@ -66,8 +87,8 @@ export class TestQueryMultiTest extends TestQueryMultiFile {
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');
@ -97,8 +119,8 @@ export class TestQueryMultiCase extends TestQueryMultiTest {
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)];
];
} }
} }
@ -120,8 +142,8 @@ export class TestQuerySingleCase extends TestQueryMultiCase {
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)];
];
} }
} }
@ -140,9 +162,13 @@ export class TestQuerySingleCase extends TestQueryMultiCase {
export function parseExpectationsForTestQuery( export function parseExpectationsForTestQuery(
rawExpectations, rawExpectations,
query, query,
wptURL 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,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

@ -2,9 +2,7 @@
* 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)
@ -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,6 +466,16 @@ class TestBuilder {
} }
class RunCaseSpecific { class RunCaseSpecific {
constructor( constructor(
testPath, testPath,
params, params,
@ -296,8 +484,8 @@ class RunCaseSpecific {
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,11 +635,12 @@ 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,
@ -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;
@ -480,11 +679,11 @@ class RunCaseSpecific {
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;
@ -494,13 +693,12 @@ class RunCaseSpecific {
// 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;
} }
@ -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) {
@ -220,8 +284,11 @@ export class TestTree {
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,7 +296,7 @@ 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);
@ -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 ''.

View file

@ -3,8 +3,7 @@
**/ /** **/ /**
* 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

@ -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.
*/ */
@ -47,9 +69,9 @@ export const kCTSOptionsInfo = {
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

@ -2,9 +2,12 @@
* 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 () => {
@ -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

@ -2,12 +2,14 @@
* 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
* (may be available in testing environments with special browser runtime flags set), or using * (may be available in testing environments with special browser runtime flags set), or using
* 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

@ -7,11 +7,11 @@ export function keysOf(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];
} }
@ -274,21 +303,65 @@ const TypedArrayBufferViewInstances = [
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

@ -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); let target = NativeObject(object);
do { do {
const descriptor = ReflectGetOwnPropertyDescriptor(target, key); const descriptor = ReflectGetOwnPropertyDescriptor(target, key);
if (descriptor !== undefined) { if (descriptor !== undefined) {
if (ObjectHasOwn(descriptor, 'get')) { if (ObjectHasOwn(descriptor, "get")) {
return descriptor.get; return descriptor.get;
} }
return; return;
} }
} while ((target = ReflectGetPrototypeOf(target)) !== null); } while ((target = ReflectGetPrototypeOf(target)) !== null);
}; };
const ObjectHasOwn = NativeObject.hasOwn || uncurryThis(ObjectPrototype.hasOwnProperty); 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);
@ -536,23 +559,19 @@ const handler = ObjectFreeze({
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