Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update print_environment to show featureLevel and defaultDevice #4130

Merged
merged 5 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/common/runtime/helper/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const kCTSOptionsInfo: OptionsInfos<CTSOptions> = {
],
},
debug: { description: 'show more info' },
compatibility: { description: 'run in compatibility mode' },
compatibility: { description: 'request adapters with featureLevel: "compatibility"' },
forceFallbackAdapter: { description: 'pass forceFallbackAdapter: true to requestAdapter' },
unrollConstEvalLoops: { description: 'unroll const eval loops in WGSL' },
powerPreference: {
Expand Down
41 changes: 27 additions & 14 deletions src/webgpu/print_environment.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ function consoleLogIfNotWPT(x: unknown) {

g.test('info')
.desc(
`Test which prints what global scope (e.g. worker type) it's running in.
Typically, tests will check for the presence of the feature they need (like HTMLCanvasElement)
and skip if it's not available.
`Test which prints what global scope (e.g. worker type) it's running in, and info about
the adapter and device that it gets.

Note, other tests should not check the global scope type to detect features; instead, they should
check for the presence of the feature they need (like HTMLCanvasElement) and skip if not available.

Run this test under various configurations to see different results
(Window, worker scopes, Node, etc.)
Expand All @@ -36,8 +38,19 @@ in the logs. On non-WPT runtimes, it will also print to the console with console
WPT disallows console.log and doesn't support logs on passing tests, so this does nothing on WPT.`
)
.fn(t => {
const isCompatibilityMode = (t.adapter as unknown as { isCompatibilityMode?: boolean })
.isCompatibilityMode;
// `t.device` will be the default device, because no additional capabilities were requested.
const defaultDeviceProperties = Object.fromEntries(
(function* () {
const device = t.device as unknown as Record<string, unknown>;
for (const key in device) {
// Skip things that we don't want to JSON.stringify.
if (['lost', 'queue', 'onuncapturederror', 'label'].includes(key)) {
continue;
}
yield [key, device[key]];
}
})()
);
kainino0x marked this conversation as resolved.
Show resolved Hide resolved

const info = JSON.stringify(
{
Expand All @@ -46,20 +59,20 @@ WPT disallows console.log and doesn't support logs on passing tests, so this doe
globalTestConfig,
baseResourcePath: getResourcePath(''),
defaultRequestAdapterOptions: getDefaultRequestAdapterOptions(),
adapter: {
isFallbackAdapter: t.adapter.isFallbackAdapter,
isCompatibilityMode,
info: t.adapter.info,
features: Array.from(t.adapter.features),
limits: t.adapter.limits,
},
// Print all of the properties of the adapter and defaultDeviceProperties. JSON.stringify
// will skip methods (e.g. adapter.requestDevice), because they're not stringifiable.
adapter: t.adapter,
defaultDevice: defaultDeviceProperties,
Copy link
Collaborator

@beaufortfrancois beaufortfrancois Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defaultDevice: defaultDeviceProperties,
defaultDevice: {
adapterInfo: device.adapterInfo,
features: device.features,
limits: device.limits
},

},
// Flatten objects with prototype chains into plain objects, using `for..in`. (Otherwise,
// properties from the prototype chain will be ignored and things will print as `{}`.)
// - Replace `undefined` with `null`.
// - Expand iterable things into arrays.
// - Flatten objects with prototype chains into plain objects, using `for..in`. (Otherwise,
// properties from the prototype chain will be ignored and things will print as `{}`.)
(_key, value) => {
if (value === undefined || value === null) return null;
if (typeof value !== 'object') return value;
if (value instanceof Array) return value;
if (Symbol.iterator in value) return Array.from(value as Iterable<unknown>);

const valueObj = value as Record<string, unknown>;
return Object.fromEntries(
Expand Down
Loading