features property
Every capability, decided once from what the device was granted — see
webgpuDeviceFeatures, which is where each answer and each absence is
explained, and which runs on the VM.
The answers the supportsX getters gave before 1.0 are these, read
through DeviceCapabilityForwarders, and none of them moved:
gpu-timestampsandtimestamp-querywhere the adapter grantedtimestamp-query—H2, written per labelled pass and read back a frame or two later.computealways —H6: storage buffers, _pipelines built from the generated compute table, passes encoded as they go, and a readback through a mappable staging buffer.float32-filterablewhere the adapter granted it, which open asks for whenever it is offered;float32-renderableis core, sosupportsFloat32Filteringanswers exactly what it did.independent-blendalways: every colour target in a WebGPU pipeline carries its own equation, and the pipeline signature keys on the list of them, so the index has always been honoured here —R8only asked.offscreen-multisample,stencil,manual-mipmapsalways.blend-constantnever, and the absence is a finding rather than a limitation. SeeWebGpuEncoder.setBlendColor, which is the refusal it promises.wireframenever: WebGPU has no polygon fill mode at all. A wireframe here is line primitives and an index buffer built for them, which is the renderer's decision — the same answer WebGL2 gives for the same reason.alpha-to-coveragealways —P7: a pipeline'salphaToCoverageEnabled, wherever the pass multisamples, which the scene pass does at four.cube-texturesalways: a cube is a six-layer texture with a"cube"view over it, and the sky pass needs one.render-to-mip-levelalways, and what it turns on is reflection probes.
The false render-to-mip-level used to be was honest when it was
written and had stopped being so. It was written beside a
createCubeRenderTarget that answered null: a probe needs a cube to draw
six views into and a chain to convolve them down,
ReflectionProbeNode.supportedOn asks for both, and answering yes to the
second while the first was missing would have handed the renderer a probe
and got a crash where a skip belonged. The cube arrived later — the
conformance suite would not let supportsCubeTextures promise a face a
pass could name and then hand back nothing — and the answer stayed false,
which by then described no missing work at all. A refusal that outlives
its reason is worse than the gap it once guarded, because nobody goes
looking behind it.
There was nothing left to build. The chain a probe wants is not a
generateMipmap — this API has none, and the engine never asks a device
for one. Renderer._prefilterProbe writes every level itself, as an
ordinary full-screen pass whose colour target names a face and a level,
and on this backend both of those are one mechanism: baseArrayLayer
picks the face and baseMipLevel picks the level on a plain 2D view,
which WebGpuTexture.attachmentView has always made. The pass's initial
viewport covers the level rather than the texture, because WebGPU takes
it from the view's own size, so §7.2's last rule needs no arithmetic here
either.
What said so is the picture rather than the reading: probe-car records
through this backend and lands on Impeller's reference at nought of a
hundred and seventy-two thousand eight hundred pixels, worst channel zero.
test/reflection_probe_test.dart asks the question the capability
actually promises: that a mirror ball between a red wall and a blue one
shows each on its own side.
Implementation
@override
late final DeviceFeatures features = webgpuDeviceFeatures(
granted: (String feature) => _gpuDevice.features.has(feature),
);