wgpu v0.30.4 - Metal Stencil State Fix for macOS

wgpu v0.30.4 was published on June 25, 2026, with a Metal fix for stencil state translation on macOS. The main effect is render correctness: stencil tests that were inert on Metal now receive the configured face states and masks. This release is not marked as a prerelease.

The full release notes and downloads are on the GitHub release page.

Metal stencil state now maps through

The central fix is in CreateRenderPipeline. The Metal backend now translates StencilFront and StencilBack into MTLDepthStencilState, including the compare function, fail operation, depth fail operation, pass operation, and read and write masks.

Before this release, Metal kept its default stencil state. The release notes call out Always plus Keep, which meant the stencil test could be present in pipeline setup yet do nothing. Vulkan, DX12, and GLES already had the path. Metal was the backend that missed it.

For web processing teams, that kind of bug is awkward because it looks like content logic rather than backend state. Rounded panels can render as square panels. Masked or clipped content can vanish. If a screenshot worker, visual diff job, or browser capture path depends on WebGPU output on macOS, this is the sort of correctness fix that changes downstream artifacts without changing application code.

Pixel formats are explicit for stencil attachments

The release also sets stencilAttachmentPixelFormat on the render pipeline descriptor when formats carry a stencil aspect. The notes name Depth24PlusStencil8, Depth32FloatStencil8, and Stencil8.

The important detail is the conditional split between depth and stencil formats. A Stencil8 only format no longer sets depthAttachmentPixelFormat as if depth data were present. The behavior now matches the Rust wgpu-hal Metal pattern cited in the notes.

This is narrow, but it matters for operators who run a mixed fleet. Format handling bugs often show up only on one backend, one device class, or one capture path. The release narrows that backend gap for macOS and Apple Silicon M4, where the fix was verified.

The enum mapping is small but not cosmetic

stencilOperationToMTL is the new explicit mapping from WebGPU stencil operations to Metal stencil operations. The release notes give the reason: enum values differ, with WebGPU Invert=4 and Metal Invert=5.

That is a plain compatibility detail, but it is the kind that should stay explicit. Passing values through by accident makes tests look valid until one backend assigns a different integer to the same idea. The mapping makes intent visible and reduces the chance that another stencil operation silently goes wrong.

The PR #227 contribution from @samyfodil also includes the descriptor cleanup. Release(depthStencilDesc) now runs after depth stencil state creation. Descriptor properties copy, so the original descriptor can be freed. That part is internal maintenance, but it is relevant for long running render workers that create many pipelines.

What to watch after upgrade

There are no breaking changes or migration steps in the release notes. The practical check is output comparison on macOS. Any tests that had accepted square corners, missing clipped content, or unchanged stencil masks may now expose the intended rendering.

I would treat this as a backend correctness update, not a feature release. It is worth testing render snapshots that use Depth24PlusStencil8, Depth32FloatStencil8, or Stencil8, especially if they feed HTML capture, image generation, or visual regression jobs.

Where to get it