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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

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

1 participant