Skip to content

Gate @interpolate(linear) behind a downlevel flag - #9972

Open
emilk wants to merge 4 commits into
gfx-rs:trunkfrom
emilk:emilk/interpolate-linear-downlevel-flag
Open

Gate @interpolate(linear) behind a downlevel flag#9972
emilk wants to merge 4 commits into
gfx-rs:trunkfrom
emilk:emilk/interpolate-linear-downlevel-flag

Conversation

@emilk

@emilk emilk commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Connections

Fixes #9971.

Description

@interpolate(linear) becomes noperspective in GLSL, which doesn't exist in GLSL ES. naga's GLSL backend rejected it, but only at pipeline creation, with The selected version doesn't support Features(NOPERSPECTIVE_QUALIFIER) — a Debug print of an internal bitflag, no shader label, no source span.

  • Add naga::valid::Capabilities::LINEAR_INTERPOLATION, required for Interpolation::Linear, and report it from every backend's supported_capabilities().
  • Add DownlevelFlags::LINEAR_INTERPOLATION and map it to that capability, so Device::create_shader_module rejects such shaders up front, with a label and a span. The GLES backend clears the flag when the shading language version is ES.
  • The GLSL backend's MissingFeatures error now names the version: GLSL 300 es doesn't support the required feature(s): NOPERSPECTIVE_QUALIFIER.

Not done here: GLES could actually support this via NV_shader_noperspective_interpolation (ES 3.0 / WebGL2 extension) rather than refusing it. The report also mentions the create_render_pipeline error never reaching on_uncaptured_error, which looks like a separate bug.

Testing

Two naga tests: validation rejects @interpolate(linear) without the capability and accepts it with, and the GLSL ES backend produces the new message.

Note that nothing catches a backend that under-advertises the new downlevel flag. I hit this while writing the PR — Vulkan builds its flags from an allowlist rather than from DownlevelCapabilities::default(), and the omission only surfaced as requestAdapter returned null in the CTS jobs. STRICT_WEBGPU_COMPLIANCE_ADAPTER looks like the test for this, but a non-compliant adapter is filtered out by the instance flag, so the test is skipped rather than failed. Worth fixing separately.

Squash or Rebase?

Ready to rebase.

Checklist

  • I self-reviewed and fully understand this PR.
  • WebGPU implementations built with wgpu may be affected behaviorally.
  • Validation and feature gates are in place to confine behavioral changes.
  • Tests demonstrate the validation and altered logic works.
  • CHANGELOG.md entries for the user-facing effects of this change are present.
  • The PR is minimal, and doesn't make sense to land as multiple PRs.
  • Commits are logically scoped and individually reviewable.
  • The PR description has enough context to understand the motivation and solution implemented.

🤖 Generated with Claude Code

… pipeline creation

`@interpolate(linear)` maps to `noperspective` in GLSL, which does not exist in
GLSL ES. naga's GLSL backend therefore rejected it, but only at pipeline
creation, deep in the backend, with `The selected version doesn't support
Features(NOPERSPECTIVE_QUALIFIER)`: no shader label, no source span, no hint
that WebGL2 was the constraint.

Add `naga::valid::Capabilities::LINEAR_INTERPOLATION` and the corresponding
`wgpu_types::DownlevelFlags::LINEAR_INTERPOLATION`, so that
`Device::create_shader_module` rejects such shaders up front with a label and a
span, like every other backend-unexpressible construct.

The GLES backend clears the downlevel flag whenever the shading language version
is ES.

Also include the GLSL version in the backend's `MissingFeatures` error, so that
the remaining paths through it are actionable too.

Fixes gfx-rs#9971

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Comment thread naga/src/back/glsl/mod.rs Outdated
emilk and others added 3 commits July 30, 2026 14:22
…t capabilities

The Vulkan backend builds its downlevel flags from an explicit allowlist rather
than from `DownlevelCapabilities::default()`, so the new flag was missing there.
That made every Vulkan adapter non-WebGPU-compliant, and thus invisible to
`InstanceFlags::STRICT_WEBGPU_COMPLIANCE`, which broke the CTS jobs with
`requestAdapter returned null`.

The `interpolate` snapshots also need `MULTISAMPLED_SHADING` (they use
`@interpolate(*, sample)`), which was previously supplied by
`Capabilities::default()` and got dropped when the tests started specifying
capabilities explicitly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The naga test already covers the validation gate, and the gpu test could not
catch a backend failing to advertise the downlevel flag: it asserted only that
shader-module creation agrees with the flag, so an adapter that wrongly omits
the flag makes it take the expect-failure branch and pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@emilk
emilk marked this pull request as ready for review July 30, 2026 12:45
@andyleiserson andyleiserson added the backend: gles Issues with GLES or WebGL label Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend: gles Issues with GLES or WebGL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@interpolate(linear) is accepted on WebGL2/GLES devices, then fails at pipeline creation with an unactionable message

3 participants