-
Notifications
You must be signed in to change notification settings - Fork 329
Description
The spec proposal currently says
When calling GPU.RequestAdapter(), passing compatibilityMode = true in the GPURequestAdapterOptions will indicate to the User Agent to select the Compatibility subset of WebGPU. Any Devices created from the resulting Adapter on supporting UAs will support only Compatibility mode. Calls to APIs unsupported by Compatibility mode will result in validation errors.
Note that a supporting User Agent may return a compatibilityMode = true Adapter which is backed by a fully WebGPU-capable hardware adapter, such as D3D12, Metal or Vulkan, so long as it validates all subsequent API calls made on the Adapter and the objects it vends against the Compatibility subset.
As a dev, I think I'd prefer that if a user agent can return core that it return core. Then, I can design my app to work if I get compat, but use more features if I get core. This seems similar to enabling features
core
const adapter = await navigator.gpu.requestAdapter();
const requiredFeatures = [];
// enable features both in the device and in my code if they exist
const canFilterF32 = adapter.features.has('float32-filterable');
if (canFilterF32) {
requiredFeatures.push('float32-filterable');
const device = adapter.requestDevice({ requiredFeatures });
...
const sampler = device.createSampler({
magFilter: canFilterF32 ? 'linear' : 'nearest',
...
});
In compat I'd like to do similar things
compat
const adapter = await navigator.gpu.requestAdapter({compatibilityMode: true});
const canUseSampleInterpolation = !adapter.isCompatibilityMode;
...
const module = device.createShaderModule({
code: canUseSampleIterpolation
? higherQualityShader
: lowerQualityShader,
});
This pattern seems intuitive to me. It will also work for some cases as a UA that doesn't support compat will return a non-compat adapter.
As it is currently implemented in Chrome, requesting compat gives you compat, period. So, the only way to do better than compat is to first request core and, only if it fails, then request compat
const adapter = await navigator.gpu.requestAdapter() ??
await navigator.gpu.requestAdapter({compatibilityMode: true});
const canUseSampleInterpolation = !adapter.isCompatibilityMode;
...
I guess it's not that bad to do two requests, although it is slower. It's also less intuitive IMO but the spec can spell out how to do it.
The disadvantage to returning core when compat is requested is that you can't test compat validation in the CTS nor in your own code without either more flags, either to requestAdapter (forceCompatibilityModeIfSupported: true
) or browser flags external to the page.
Whichever direction (1) return core if you can (2) return compat if requested, should it be specified which? The current proposal says "a supporting User Agent may return a compatibilityMode = true Adapter". Should that "may" change to "must" or "must not" or stay as "may"?
Note that regardless of these issues, a UA can of course completely ignore compatibility mode.