Skip to content

release: v0.34.12 - #391

Merged
kolkov merged 9 commits into
mainfrom
release/v0.34.12
Nov 9, 2026
Merged

kolkov merged 9 commits into
mainfrom
release/v0.34.12

Conversation

@kolkov

@kolkov kolkov commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Release v0.34.12.

A Vulkan shader-feature patch: shaders use only what the device enabled, discard follows WGSL, and naga's GPU
readback corpus runs on every adapter in the test suite.

Fixed

  • Vulkan: WGSL dot4I8Packed and dot4U8Packed no longer emit instructions the device never enabled (P2-VK-014). naga got no capability set, treated every capability as available and wrote the native packed dot product, which needs shaderIntegerDotProduct; the validation layer reported VUID-VkShaderModuleCreateInfo-pCode-08740 on Intel and NVIDIA. The device now gives naga its SPIR-V capabilities as Rust wgpu-hal does, so naga polyfills the dot product where the feature is missing, and VK_KHR_shader_integer_dot_product is enabled wherever it is supported.
  • Software: a discarded fragment stays a helper for its quad, as on the GPU backends (P3-SW-035). The interpreter ended the lane at discard, so a fine derivative taken afterwards in its row or column came from the other row instead — wrong for any value that is not linear in the other coordinate. WGSL discard now compiles to OpDemoteToHelperInvocation on the software backend, and the interpreter runs the lane on as a helper (no storage, atomic or color writes) to the end of the shader, including when the discard sits in a called function. The README's known gap is gone.
  • hal/software and its shader and raster packages are consistently excluded from js/wasm builds. Nineteen files had no build constraint, so a wasm build of these packages failed to compile instead of reporting them as not built for wasm, as hal/allbackends does; in a browser, wgpu uses the browser's WebGPU.

Changed

  • Vulkan: discard now demotes the fragment to a helper invocation instead of terminating it (P2-VK-018). On Vulkan devices with VK_EXT_shader_demote_to_helper_invocation (promoted to Vulkan 1.3), discard follows WGSL's semantics: a discarded fragment keeps running until the end of the shader, writing nothing to storage or to its color targets, so derivatives in the rest of its quad stay defined. A shader that does heavy work after a discard now pays for it on the discarded fragments too. It used to be lowered to OpKill, which ends the invocation and leaves the quad's later derivatives undefined. Devices without the extension keep OpKill; the choice matches Dawn on Vulkan. New readback tests pin, on every backend, that a store before discard lands while one after it does not (also when the discard is in a called function), and that the quad's fine derivatives stay exact after a lane discards, including for a value that depends on both coordinates.
  • naga v0.21.8. WGSL now rejects what the spec never allowed: a function-scope var outside the function address space (var<workgroup> in a function body was silently lowered to a function variable), and an integer division, remainder or shift by a const-expression zero or past the bit width. No shader in this module was affected. DXIL reads a 32-bit storage element of more than four components with dx.op.bufferLoad, as DXC does, so it no longer needs shader model 6.2.
  • gpucontext v0.32.0 (the new IME contract, ADR-045). wgpu uses none of the changed types; hosts that implement IMEController follow gpucontext's migration notes.

Added

  • TestReadbackCorpus runs naga's GPU readback corpus on every adapter of every backend (P1-INFRA-001). The corpus holds compute shaders and the exact words a GPU must write; static validators accept miscompiles that only a readback catches. The test finds the corpus through the naga version the module resolves (its testdata/readback), reads the corpus format strictly, opens each adapter with the features its cases require, and reports each case as PASS, FAIL, an expected failure with its card, an unexpected pass (which fails the test) or a skip. On Vulkan a validation-layer message during a case fails that case. The hand copy of flow/short-circuit-or-rt is gone: the corpus has the case.

Checked before this PR: go test ./... with the Vulkan validation layer (30/30 packages), golangci-lint on windows, linux and darwin, builds for js/wasm, -tags rust and 386, and naga's readback corpus on every adapter here (664 pass, one listed expected failure). gg, gogpu, g3d and ui ran their suites against this tree before the PR.

naga v0.21.8 rejects WGSL the spec never allowed (function-scope var
outside the function address space, const-expression division by zero
and over-wide shifts; no shader in this module is affected), lets DXIL
read 32-bit storage elements without shader model 6.2, and drops the
four stale gogpu/wgpu:P1-SW-013 known failures from its readback corpus.
gpucontext v0.32.0 carries the new IME contract, which wgpu does not use.

TestDXILShaderModelRefusal followed the old DXIL rule: a five-component
32-bit storage element now compiles at every shader model from 6.0, as
DXC writes it (naga P1-DXIL-072), so the test asserts that, and checks
the refusal path with a 64-bit element, which still needs SM 6.3.
…orpus)

naga's testdata/readback holds compute shaders and the exact words a GPU must
write. Until now wgpu ran it only through throwaway gate runners and hand
copies (flow/short-circuit-or-rt), so a corpus case never ran in this repo's
tests. TestReadbackCorpus finds the corpus through go list -m (go.work
locally, the go.mod pin in CI), reads formats 1 and 2 strictly, opens each
adapter with the features its cases require, and reports PASS, FAIL,
XFAIL(card), XPASS(close card) or SKIP per backend, adapter and case. A
known failure that passes fails the test; on Vulkan a validation message
during a case fails that case.

halRunner now takes a dispatch of any binding kinds, entry point and
workgroup count; TestOverridesAllAdapters shares forEachHALAdapter and so
runs Vulkan under the validation layer too. Self-tests cover the reader's
rejections and prove a corrupted expectation fails on the software device.
The hand copy of flow/short-circuit-or-rt is gone: the corpus has the case.
…ifies

The interpreter ended a lane at discard (OpKill), so a fine derivative
taken later in its quad row or column came from the other row: wrong for
any value not linear in the other coordinate (P3-SW-035). The software
device now asks naga for OpDemoteToHelperInvocation, and the interpreter
runs the demoted lane to the end of the shader as a helper: no storage,
atomic or color writes, values still feeding the quad's derivatives.
A demotion inside a called function marks every frame of the invocation,
so the caller's stores after the call are dropped too. When the lane
ends, the entry point still reports ErrDiscarded, so the rasterizer's
discard handling is unchanged.

TestDerivativesAfterDiscard now also takes fine derivatives of x*y, the
case that tells a helper feeding its own row from a difference taken in
the other row; it failed on the software backend before this change.
TestDiscardStorageWrites covers a discard in a called function, which
fails when the demotion marks only the callee's frame.
…lds consistently

Nineteen files of hal/software, hal/software/shader and
hal/software/raster had no build constraint while every other file of
these packages excludes js/wasm, so a wasm build or vet of them failed
to compile instead of reporting them as not built there, as
hal/allbackends does. The package doc now says so: in a browser wgpu
uses the browser's WebGPU. stats.go also drops a comment that cited an
internal document path.
@codecov

codecov Bot commented Nov 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

naga v0.21.9 names the five SPIR-V capabilities the Vulkan backend passes it and carries the Metal Paravirtual known failure for vars/workgroup-split-rt. Its compiler output is unchanged from v0.21.8.
naga v0.21.9 exports StorageImageWriteWithoutFormat, DrawParameters, RayQueryKHR, DotProductInputAll and DotProductInput4x8Bit, so the local copies of their values go.
The hal/allbackends tests compared and keyed maps by backend names written as literals ("vulkan", "gles", "dx12-fxc"...), and the corpus known failures matched on them: a misspelled one compiled and silently matched nothing. They are now a backendName type with one constant per backend, which the corpus format also decodes into. The Vulkan capability test names its rows after the requested features (Feature.String) and runs each as a subtest.
@kolkov
kolkov merged commit 40e3fde into main Nov 9, 2026
19 checks passed
@kolkov
kolkov deleted the release/v0.34.12 branch November 9, 2026 10:21
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.

1 participant