Skip to content

Commit

Permalink
[WebGPU] newly added depth comparison tests are failing
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=271330
<radar://125104840>

Reviewed by Dan Glastonbury.

The 1 / uint16::max() addition was known to be wrong, it should have been
0.5 / uint16::max() but that didn't work when I tried initially.

It is because the result did not fit into a float and was still being truncated.

Additionally update the CTS tests which caught this failure.

* Source/WebGPU/WebGPU/RenderPassEncoder.mm:
(WebGPU::RenderPassEncoder::quantizedDepthValue):

Canonical link: https://commits.webkit.org/276444@main
  • Loading branch information
mwyrzykowski committed Mar 21, 2024
1 parent 119a9a9 commit c3b657c
Show file tree
Hide file tree
Showing 992 changed files with 30,994 additions and 3,978 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@











Expand All @@ -28,5 +33,6 @@ export const globalTestConfig = {
testHeartbeatCallback: () => {},
noRaceWithRejectOnTimeout: false,
unrollConstEvalLoops: false,
compatibility: false
compatibility: false,
forceFallbackAdapter: false
};
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ function compareOneLevel(ordering, aIsBig, bIsBig) {
return Ordering.Unordered;
}

function comparePaths(a, b) {
/**
* Compare two file paths, or file-local test paths, returning an Ordering between the two.
*/
export function comparePaths(a, b) {
const shorter = Math.min(a.length, b.length);

for (let i = 0; i < shorter; ++i) {
Expand Down
6 changes: 3 additions & 3 deletions LayoutTests/http/tests/webgpu/common/internal/query/query.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/import { optionEnabled } from '../../runtime/helper/options.js';import { assert, unreachable } from '../../util/util.js';
**/import { optionString } from '../../runtime/helper/options.js';import { assert, unreachable } from '../../util/util.js';


import { compareQueries, Ordering } from './compare.js';
Expand Down Expand Up @@ -188,12 +188,12 @@ wptURL)
assert(
expectationURL.pathname === wptURL.pathname,
`Invalid expectation path ${expectationURL.pathname}
Expectation should be of the form path/to/cts.https.html?worker=0&q=suite:test_path:test_name:foo=1;bar=2;...
Expectation should be of the form path/to/cts.https.html?debug=0&q=suite:test_path:test_name:foo=1;bar=2;...
`
);

const params = expectationURL.searchParams;
if (optionEnabled('worker', params) !== optionEnabled('worker', wptURL.searchParams)) {
if (optionString('worker', params) !== optionString('worker', wptURL.searchParams)) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ class TestBuilder {
const testcaseStringUnique = stringifyPublicParamsUniquely(params);
assert(
!seen.has(testcaseStringUnique),
`Duplicate public test case+subcase params for test ${testPathString}: ${testcaseString}`
`Duplicate public test case+subcase params for test ${testPathString}: ${testcaseString} (${caseQuery})`
);
seen.add(testcaseStringUnique);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/ // 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).
// 'out/{cts,unittests}/listing.js' files (see tools/gen_listings_and_webworkers).
export {};
2 changes: 1 addition & 1 deletion LayoutTests/http/tests/webgpu/common/internal/version.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// AUTO-GENERATED - DO NOT EDIT. See tools/gen_version.

export const version = 'e05aad58e94fa357a38e6b20160c37e74e8d19a6';
export const version = '390191015c725c89e4965e9c57c2ca994b534db4';
16 changes: 14 additions & 2 deletions LayoutTests/http/tests/webgpu/common/runtime/helper/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ searchParams = getWindowURL().searchParams)




export const kDefaultCTSOptions = {
worker: false,
worker: '',
debug: true,
compatibility: false,
forceFallbackAdapter: false,
unrollConstEvalLoops: false,
powerPreference: ''
};
Expand All @@ -59,9 +61,19 @@ export const kDefaultCTSOptions = {
* Options to the CTS.
*/
export const kCTSOptionsInfo = {
worker: { description: 'run in a worker' },
worker: {
description: 'run in a worker',
parser: optionString,
selectValueDescriptions: [
{ value: '', description: 'no worker' },
{ value: 'dedicated', description: 'dedicated worker' },
{ value: 'shared', description: 'shared worker' },
{ value: 'service', description: 'service worker' }]

},
debug: { description: 'show more info' },
compatibility: { description: 'run in compatibility mode' },
forceFallbackAdapter: { description: 'pass forceFallbackAdapter: true to requestAdapter' },
unrollConstEvalLoops: { description: 'unroll const eval loops in WGSL' },
powerPreference: {
description: 'set default powerPreference for some tests',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,22 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/import { setBaseResourcePath } from '../../framework/resources.js';import { globalTestConfig } from '../../framework/test_config.js';import { DefaultTestFileLoader } from '../../internal/file_loader.js';
import { Logger } from '../../internal/logging/logger.js';
import { parseQuery } from '../../internal/query/parseQuery.js';

import { setDefaultRequestAdapterOptions } from '../../util/navigator_gpu.js';
**/import { setBaseResourcePath } from '../../framework/resources.js';import { DefaultTestFileLoader } from '../../internal/file_loader.js';import { parseQuery } from '../../internal/query/parseQuery.js';
import { assert } from '../../util/util.js';

import { setupWorkerEnvironment } from './utils_worker.js';


// Should be DedicatedWorkerGlobalScope, but importing lib "webworker" conflicts with lib "dom".
// Should be WorkerGlobalScope, but importing lib "webworker" conflicts with lib "dom".



const loader = new DefaultTestFileLoader();

setBaseResourcePath('../../../resources');

self.onmessage = async (ev) => {
const query = ev.data.query;
const expectations = ev.data.expectations;
const ctsOptions = ev.data.ctsOptions;

const { debug, unrollConstEvalLoops, powerPreference, compatibility } = ctsOptions;
globalTestConfig.unrollConstEvalLoops = unrollConstEvalLoops;
globalTestConfig.compatibility = compatibility;

Logger.globalDebugMode = debug;
const log = new Logger();
async function reportTestResults(ev) {
const { query, expectations, ctsOptions } = ev.data;

if (powerPreference || compatibility) {
setDefaultRequestAdapterOptions({
...(powerPreference && { powerPreference }),
// MAINTENANCE_TODO: Change this to whatever the option ends up being
...(compatibility && { compatibilityMode: true })
});
}
const log = setupWorkerEnvironment(ctsOptions);

const testcases = Array.from(await loader.loadCases(parseQuery(query)));
assert(testcases.length === 1, 'worker query resulted in != 1 cases');
Expand All @@ -44,5 +25,17 @@ self.onmessage = async (ev) => {
const [rec, result] = log.record(testcase.query.toString());
await testcase.run(rec, expectations);

self.postMessage({ query, result });
this.postMessage({ query, result });
}

self.onmessage = (ev) => {
void reportTestResults.call(ev.source || self, ev);
};

self.onconnect = (event) => {
const port = event.ports[0];

port.onmessage = (ev) => {
void reportTestResults.call(port, ev);
};
};
143 changes: 121 additions & 22 deletions LayoutTests/http/tests/webgpu/common/runtime/helper/test_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,147 @@
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/import { LogMessageWithStack } from '../../internal/logging/log_message.js';

import { timeout } from '../../util/timeout.js';
import { assert } from '../../util/util.js';

import { kDefaultCTSOptions } from './options.js';

export class TestWorker {

/** Query all currently-registered service workers, and unregister them. */
function unregisterAllServiceWorkers() {
void navigator.serviceWorker.getRegistrations().then((registrations) => {
for (const registration of registrations) {
void registration.unregister();
}
});
}

// NOTE: This code runs on startup for any runtime with worker support. Here, we use that chance to
// delete any leaked service workers, and register to clean up after ourselves at shutdown.
unregisterAllServiceWorkers();
window.addEventListener('beforeunload', () => {
unregisterAllServiceWorkers();
});

class TestBaseWorker {

resolvers = new Map();

constructor(ctsOptions) {
this.ctsOptions = { ...(ctsOptions || kDefaultCTSOptions), ...{ worker: true } };
const selfPath = import.meta.url;
const selfPathDir = selfPath.substring(0, selfPath.lastIndexOf('/'));
const workerPath = selfPathDir + '/test_worker-worker.js';
this.worker = new Worker(workerPath, { type: 'module' });
this.worker.onmessage = (ev) => {
const query = ev.data.query;
const result = ev.data.result;
if (result.logs) {
for (const l of result.logs) {
Object.setPrototypeOf(l, LogMessageWithStack.prototype);
}
constructor(worker, ctsOptions) {
this.ctsOptions = { ...(ctsOptions || kDefaultCTSOptions), ...{ worker } };
}

onmessage(ev) {
const query = ev.data.query;
const result = ev.data.result;
if (result.logs) {
for (const l of result.logs) {
Object.setPrototypeOf(l, LogMessageWithStack.prototype);
}
this.resolvers.get(query)(result);
}
this.resolvers.get(query)(result);
this.resolvers.delete(query);

// MAINTENANCE_TODO(kainino0x): update the Logger with this result (or don't have a logger and
// update the entire results JSON somehow at some point).
};
// MAINTENANCE_TODO(kainino0x): update the Logger with this result (or don't have a logger and
// update the entire results JSON somehow at some point).
}

async run(
async makeRequestAndRecordResult(
target,
rec,
query,
expectations = [])
expectations)
{
this.worker.postMessage({
const request = {
query,
expectations,
ctsOptions: this.ctsOptions
});
};
target.postMessage(request);

const workerResult = await new Promise((resolve) => {
assert(!this.resolvers.has(query), "can't request same query twice simultaneously");
this.resolvers.set(query, resolve);
});
rec.injectResult(workerResult);
}
}

export class TestDedicatedWorker extends TestBaseWorker {


constructor(ctsOptions) {
super('dedicated', ctsOptions);
const selfPath = import.meta.url;
const selfPathDir = selfPath.substring(0, selfPath.lastIndexOf('/'));
const workerPath = selfPathDir + '/test_worker-worker.js';
this.worker = new Worker(workerPath, { type: 'module' });
this.worker.onmessage = (ev) => this.onmessage(ev);
}

async run(
rec,
query,
expectations = [])
{
await this.makeRequestAndRecordResult(this.worker, rec, query, expectations);
}
}

export class TestWorker extends TestDedicatedWorker {}

export class TestSharedWorker extends TestBaseWorker {


constructor(ctsOptions) {
super('shared', ctsOptions);
const selfPath = import.meta.url;
const selfPathDir = selfPath.substring(0, selfPath.lastIndexOf('/'));
const workerPath = selfPathDir + '/test_worker-worker.js';
const worker = new SharedWorker(workerPath, { type: 'module' });
this.port = worker.port;
this.port.start();
this.port.onmessage = (ev) => this.onmessage(ev);
}

async run(
rec,
query,
expectations = [])
{
await this.makeRequestAndRecordResult(this.port, rec, query, expectations);
}
}

export class TestServiceWorker extends TestBaseWorker {
constructor(ctsOptions) {
super('service', ctsOptions);
}

async run(
rec,
query,
expectations = [])
{
const [suite, name] = query.split(':', 2);
const fileName = name.split(',').join('/');
const serviceWorkerURL = new URL(
`/out/${suite}/webworker/${fileName}.worker.js`,
window.location.href
).toString();

// If a registration already exists for this path, it will be ignored.
const registration = await navigator.serviceWorker.register(serviceWorkerURL, {
type: 'module'
});
// Make sure the registration we just requested is active. (We don't worry about it being
// outdated from a previous page load, because we wipe all service workers on shutdown/startup.)
while (!registration.active || registration.active.scriptURL !== serviceWorkerURL) {
await new Promise((resolve) => timeout(resolve, 0));
}
const serviceWorker = registration.active;

navigator.serviceWorker.onmessage = (ev) => this.onmessage(ev);
await this.makeRequestAndRecordResult(serviceWorker, rec, query, expectations);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/import { globalTestConfig } from '../../framework/test_config.js';import { Logger } from '../../internal/logging/logger.js';
import { setDefaultRequestAdapterOptions } from '../../util/navigator_gpu.js';









/**
* Set config environment for workers with ctsOptions and return a Logger.
*/
export function setupWorkerEnvironment(ctsOptions) {
const { debug, unrollConstEvalLoops, powerPreference, compatibility } = ctsOptions;
globalTestConfig.unrollConstEvalLoops = unrollConstEvalLoops;
globalTestConfig.compatibility = compatibility;

Logger.globalDebugMode = debug;
const log = new Logger();

if (powerPreference || compatibility) {
setDefaultRequestAdapterOptions({
...(powerPreference && { powerPreference }),
// MAINTENANCE_TODO: Change this to whatever the option ends up being
...(compatibility && { compatibilityMode: true })
});
}

return log;
}
Loading

0 comments on commit c3b657c

Please sign in to comment.