Skip to content

refactor(webgpu): data-driven gating for WGSL built-in inputs#8739

Merged
mvaligursky merged 1 commit into
mainfrom
mv-wgsl-builtin-gating
May 18, 2026
Merged

refactor(webgpu): data-driven gating for WGSL built-in inputs#8739
mvaligursky merged 1 commit into
mainfrom
mv-wgsl-builtin-gating

Conversation

@mvaligursky
Copy link
Copy Markdown
Contributor

Follow-up to #8733. Generalizes the WebGPU shader processor's gating of optional WGSL built-in inputs so that all stages are handled consistently, fixes a regression that produced invalid WGSL for shaders without varyings, and restructures the emission to be data-driven so adding a new built-in is a one-row change.

Fixes:

  • Empty FragmentInput struct (invalid WGSL) for fragment shaders with no varyings and no pc* references (e.g. the gizmo-unlit shader). A sentinel built-in is now emitted only when the input struct would otherwise be empty.
  • Detection now also recognises struct-field access (input.frontFacing, input.sampleIndex, ...), not only the pc* global form. Both forms are documented as supported in wgsl-specifics.md.
  • Word-boundary regex (instead of String.includes) prevents false positives on identifiers containing the name as a substring.

Changes:

  • New FRAGMENT_BUILTINS / VERTEX_BUILTINS tables describe each optional built-in (name, type, @builtin(...), public pc* global, optional feature flag, optional sentinel role).
  • Vertex inputs vertex_index / instance_index are now gated symmetrically with the fragment built-ins (previously always emitted). Gating uses both pcVertexIndex / pcInstanceIndex and input.vertexIndex / input.instanceIndex.
  • Sentinel fallback per stage (position for fragment, vertex_index for vertex) keeps input structs non-empty even when nothing else is referenced.
  • `processAttributes` signature extended with `device`, `source`, `entryInputName` (internal only).
  • `copyInputs` left to do its own `ENTRY_FUNCTION` match against the post-`renameUniformAccess` source, since cached match positions would be invalidated by source-modifying passes.

No public API changes — all changes are internal to the WGSL shader processor. Behaviour for existing engine shaders is unchanged (the few vertex chunks that reference `pcVertexIndex` / `pcInstanceIndex` continue to receive those built-ins; the rest now no longer carry two unused inputs).

Follow-up to #8733. Generalizes gating of optional WGSL built-in inputs
across all stages, fixes invalid WGSL for shaders without varyings, and
restructures emission to be data-driven.

Fixes:
- Empty FragmentInput struct for fragment shaders with no varyings and
  no pc* references (e.g. gizmo-unlit). Sentinel built-in emitted only
  when struct would otherwise be empty.
- Detection now recognises both pc* globals and input.field access.
- Word-boundary regex prevents identifier-substring false positives.

Changes:
- FRAGMENT_BUILTINS / VERTEX_BUILTINS tables describe each optional
  built-in; adding one is a single-row change.
- vertex_index / instance_index now gated symmetrically with fragment
  built-ins (previously always emitted).
- Per-stage sentinel fallback (position for fragment, vertex_index for
  vertex) guarantees non-empty input structs.
- processAttributes signature extended with device, source,
  entryInputName (internal only).
- copyInputs re-runs ENTRY_FUNCTION match against the post-rename
  source to avoid stale brace positions.
@mvaligursky mvaligursky self-assigned this May 18, 2026
@mvaligursky mvaligursky added the area: graphics Graphics related issue label May 18, 2026
@mvaligursky mvaligursky merged commit c0d051c into main May 18, 2026
8 checks passed
@mvaligursky mvaligursky deleted the mv-wgsl-builtin-gating branch May 18, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: graphics Graphics related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant