Skip to content

Upgrade to wgpu 30 - #24841

Merged
alice-i-cecile merged 27 commits into
bevyengine:mainfrom
ChristopherBiscardi:wgpu-30
Jul 16, 2026
Merged

alice-i-cecile merged 27 commits into
bevyengine:mainfrom
ChristopherBiscardi:wgpu-30

Conversation

@ChristopherBiscardi

@ChristopherBiscardi ChristopherBiscardi commented Jul 2, 2026 •

Copy link
Copy Markdown
Member

Objective

Upgrade to wgpu 30

Solution

  • Update and merge naga_oil
    • Publish naga_oil
  • Update and merge dlss_wgpu
    • publish dlss_wgpu
  • remove dependency patches for naga_oil and dlss_wgpu

Relevant Changes

Testing

  • 3d_scene
  • solari with dlss

Showcase

3d_scene on macos

image

ssao on macos

image

bevy_city on macos

image

Solari on Windows 11

image

Comment thread Cargo.toml Resolved

@Zeophlite Zeophlite left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve all but Solaris changes

Comment thread crates/bevy_render/src/error_handler.rs Resolved
@ChristopherBiscardi

Copy link
Copy Markdown
Member Author

CI is passing except for the building of the integration tests because of the patches.

@Zeophlite Zeophlite added A-Rendering Drawing game state to the screen D-Straightforward Simple bug fixes and API improvements, docs, test and examples labels Jul 2, 2026

@stuartparmenter stuartparmenter left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the changes look good. I've been testing Bevy w/ wgpu v30 (and trunk right before v30) for the last 6 weeks or so, and have been doing additional testing moving over to this PR. My game, tests, etc all work fine.

The solari change will have a conflict if #24767 lands first (which it probably will)

@ChristopherBiscardi

Copy link
Copy Markdown
Member Author

The example run differences seem to be caused by something on main, where examples like world_serialization and custom_skinned_mesh are failing with panics.

@JMS55 JMS55 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving solari changes

@ChristopherBiscardi ChristopherBiscardi added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Blocked This cannot move forward until something else changes S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jul 15, 2026
@alice-i-cecile
alice-i-cecile added this pull request to the merge queue Jul 16, 2026
Merged via the queue into bevyengine:main with commit 5036d97 Jul 16, 2026
43 of 44 checks passed
@github-project-automation github-project-automation Bot moved this from Needs SME Triage to Done in Rendering Jul 16, 2026
stuartparmenter added a commit to stuartparmenter/bevy that referenced this pull request Jul 17, 2026
Upstream upgraded to wgpu 30 (bevyengine#24841), which contains all of the wgpu
HDR work our [patch] pin pointed at (a03be8d2 is an ancestor of
v30.0.0), so the git pins are dropped and wgpu/wgpu-types/naga/
wgpu-naga-bridge now resolve to crates.io 30.0.0.

Most code conflicts were upstream independently making the same wgpu 30
API migration this branch already carried via the trunk pin; kept our
sides where they had more specific expect messages or the HDR surface
negotiation, and adopted upstream's present(&RenderQueue) signature.
Also removes the two #[expect(clippy::large_enum_variant)] workarounds
obsoleted by upstream boxing RenderResources.
pull Bot pushed a commit to orzogc/bevy that referenced this pull request Jul 28, 2026
# Objective

[Ray tracing on Metal](gfx-rs/wgpu#8071) has
been available since wgpu 29.

I shipped a PR to wgpu for [implementing bindless storage
buffers](gfx-rs/wgpu#9081) for metal, which was
released with wgpu 30. With the [wgpu 30
PR](bevyengine#24841) in bevy merged, we
are fully ready to add support to Solari on metal backends!

However because there is a limit of 31 buffer slots per shader stage.
Running Solari on main on a raytracing compatible Mac results in a
crash.

## Solution

I had combine the world cache into a single packed buffer. In theory
this should not introduce performance regressions since it’s only
reorganizing bindings and doesn’t introduce and copy or other passes.
Tried keeping the diff fairly minimal and easy to review.

Getting the buffer layout for the world cache on the CPU with
`ShaderType` was tricky. To avoid blowing up memory I put it in a
private module so you can't construct it.

## Testing

- Ran the Solari example on mac

```
cargo run --example solari --features bevy_solari,https,free_camera
```

Currently this PR needs a benchmark against main to ensure there's no
perf regression. I could use some help with that!

---

## Showcase

<img width="2566" height="1514" alt="shot"
src="https://github.com/user-attachments/assets/691b9bd3-129f-47e6-8efe-313cbadd6ff5"
/>

## Known limitations

Tracing spans incorrectly report 0.0ms , tracking in
gfx-rs/wgpu#9414

No denoising support yet. Could theoretically use [MetalFX Ray
Reconstruction](https://crates.io/crates/objc2-metal-fx) in place of
DLSS for cross-platform denoising support in Solari. In the longer term
we are also looking at Open Image Denoise 3.0 that promises temporal
denoising support.

---------

Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
bigmark222 added a commit to bigmark222/bevy that referenced this pull request Aug 11, 2026
Brings the branch up to date with upstream/main (434 commits, through
`e8b3598ff`, post-0.19.0). Two upstream changes required real porting
work rather than conflict resolution:

**WESL migration (bevyengine#25088).** All 160 in-tree shaders moved `.wgsl` ->
`.wesl` and naga_oil was removed. Every shader this branch touches was
renamed, and the branch's 248 added naga_oil directive lines are no
longer valid syntax. Ported:

- `#ifdef X` / `#else` / `#endif` -> `@if(X)` / `@else`, using the
  attribute form rather than the `{ }` block form wherever the guarded
  declaration escapes the block (WESL's block form is a compound
  statement and would scope `let`/`var` bindings). Nested
  MULTIVIEW-inside-MULTISAMPLED guards collapse to combined conditions
  (`@if(MULTIVIEW && !MULTISAMPLED)` / `@elif`).
- `array<View, #{MAX_VIEW_COUNT}>` -> `array<View, constants::MAX_VIEW_COUNT>`.
  `ShaderDefVal::UInt` survived the migration and now injects the value
  as a WGSL `const` through a virtual `constants` module, so the
  runtime-sized view array keeps working without a redesign.
- `#import` -> WESL `import`, and `bevy_pbr::mesh_view_bindings` ->
  `bevy_pbr::render::mesh_view_bindings` for the reorganized module tree.
- `input_texture.wgsl` (added by this branch) becomes `input_texture.wesl`
  and is registered via `load_shader_library!`.

**wgpu 30 (bevyengine#24841) plus the depth-attachment rework (bevyengine#24725, bevyengine#25043).**
`ViewDepthTexture`/`DepthAttachment` were replaced by
`ViewDepthStencilTexture`/`DepthStencilAttachment` +
`DepthStencilViewAttachment` + `DepthStencilViews`. The branch's
per-layer depth API was rebuilt on that shape:

- `DepthAttachment::new_multi_layer` is gone and no longer needed —
  `DepthStencilAttachment` already carries the `CachedTexture`, so
  per-layer views are always constructible.
- `get_attachment_for_layer` now lives on `DepthStencilAttachment` and
  handles all three aspect variants, with per-layer first-call latches
  for depth and stencil seeded from the whole-texture latches (same
  semantics as before: a consumer running after an earlier pass in the
  frame loads instead of re-clearing).
- Per-layer views mirror whichever aspect `attachment_view()` would
  hand out, so they stay renderable the same way.

Also reconciled against `PostProcessBindGroupCache` (bevyengine#22894), the render
phase changes (bevyengine#24980), ECS render-world window data (bevyengine#25005),
`auxiliary_entity` becoming `Option<Entity>` (bevyengine#25119), and upstream's
SSAO/prepass accessor renames (`depth_view()` -> `depth_only_view()`).

Verification:

- `cargo check --workspace` clean, no new warnings.
- 9 branch unit tests pass (5 `DynamicArrayUniformBuffer`, 4 `Multiview`).
- All four byte-deterministic smoke witnesses are **bit-identical**
  (`cmp`) to the same examples captured on clean `upstream/main`:
  `3d_scene` (697355), `volumetric_fog` (3709230),
  `deferred_rendering` (3627981), `motion_blur` (4492281). Zero shader
  compilation errors. The non-multiview path is unchanged.

Note that three of those four baselines shifted from their pre-merge
values because upstream changed them; they were re-captured on clean
upstream/main before comparison. `3d_scene` came through the whole
migration byte-identical to its old value.

The multiview path still cannot be exercised on macOS Metal (no wgpu
multiview support there), so it remains verified by static reasoning
plus the non-multiview witnesses, as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
bigmark222 added a commit to bigmark222/bevy that referenced this pull request Aug 13, 2026
Brings the branch up to date with upstream/main (434 commits, through
`e8b3598ff`, post-0.19.0). Two upstream changes required real porting
work rather than conflict resolution:

**WESL migration (bevyengine#25088).** All 160 in-tree shaders moved `.wgsl` ->
`.wesl` and naga_oil was removed. Every shader this branch touches was
renamed, and the branch's 248 added naga_oil directive lines are no
longer valid syntax. Ported:

- `#ifdef X` / `#else` / `#endif` -> `@if(X)` / `@else`, using the
  attribute form rather than the `{ }` block form wherever the guarded
  declaration escapes the block (WESL's block form is a compound
  statement and would scope `let`/`var` bindings). Nested
  MULTIVIEW-inside-MULTISAMPLED guards collapse to combined conditions
  (`@if(MULTIVIEW && !MULTISAMPLED)` / `@elif`).
- `array<View, #{MAX_VIEW_COUNT}>` -> `array<View, constants::MAX_VIEW_COUNT>`.
  `ShaderDefVal::UInt` survived the migration and now injects the value
  as a WGSL `const` through a virtual `constants` module, so the
  runtime-sized view array keeps working without a redesign.
- `#import` -> WESL `import`, and `bevy_pbr::mesh_view_bindings` ->
  `bevy_pbr::render::mesh_view_bindings` for the reorganized module tree.
- `input_texture.wgsl` (added by this branch) becomes `input_texture.wesl`
  and is registered via `load_shader_library!`.

**wgpu 30 (bevyengine#24841) plus the depth-attachment rework (bevyengine#24725, bevyengine#25043).**
`ViewDepthTexture`/`DepthAttachment` were replaced by
`ViewDepthStencilTexture`/`DepthStencilAttachment` +
`DepthStencilViewAttachment` + `DepthStencilViews`. The branch's
per-layer depth API was rebuilt on that shape:

- `DepthAttachment::new_multi_layer` is gone and no longer needed —
  `DepthStencilAttachment` already carries the `CachedTexture`, so
  per-layer views are always constructible.
- `get_attachment_for_layer` now lives on `DepthStencilAttachment` and
  handles all three aspect variants, with per-layer first-call latches
  for depth and stencil seeded from the whole-texture latches (same
  semantics as before: a consumer running after an earlier pass in the
  frame loads instead of re-clearing).
- Per-layer views mirror whichever aspect `attachment_view()` would
  hand out, so they stay renderable the same way.

Also reconciled against `PostProcessBindGroupCache` (bevyengine#22894), the render
phase changes (bevyengine#24980), ECS render-world window data (bevyengine#25005),
`auxiliary_entity` becoming `Option<Entity>` (bevyengine#25119), and upstream's
SSAO/prepass accessor renames (`depth_view()` -> `depth_only_view()`).

Verification:

- `cargo check --workspace` clean, no new warnings.
- 9 branch unit tests pass (5 `DynamicArrayUniformBuffer`, 4 `Multiview`).
- All four byte-deterministic smoke witnesses are **bit-identical**
  (`cmp`) to the same examples captured on clean `upstream/main`:
  `3d_scene` (697355), `volumetric_fog` (3709230),
  `deferred_rendering` (3627981), `motion_blur` (4492281). Zero shader
  compilation errors. The non-multiview path is unchanged.

Note that three of those four baselines shifted from their pre-merge
values because upstream changed them; they were re-captured on clean
upstream/main before comparison. `3d_scene` came through the whole
migration byte-identical to its old value.

The multiview path still cannot be exercised on macOS Metal (no wgpu
multiview support there), so it remains verified by static reasoning
plus the non-multiview witnesses, as before.
joelawm pushed a commit to joelawm/bevy that referenced this pull request Sep 8, 2026
# Objective

Upgrade to [wgpu
30](https://github.com/gfx-rs/wgpu/releases/tag/v30.0.0)

## Solution

- [x] Update and merge
[naga_oil](bevyengine/naga_oil#139)
	- [x] Publish naga_oil
- [x] Update and merge
[dlss_wgpu](bevyengine/dlss_wgpu#31)
	- [x] publish dlss_wgpu
- [x] remove dependency patches for naga_oil and dlss_wgpu

### Relevant Changes

- new NoopBackendOptions fields:
gfx-rs/wgpu#9119
- SurfaceColorSpace: gfx-rs/wgpu#9658
- get_mapped_range returns a Result:
gfx-rs/wgpu#9281
- empty BufferSlices no longer panic:
gfx-rs/wgpu#8505
- vertex buffer slots are optional now:
gfx-rs/wgpu#9351
- `SurfaceTexture::present()` has been replaced by
`Queue::present(surface_texture)`:
gfx-rs/wgpu#9361
- Disallow direct access to atomic variables in WGSL front-end (e.g. let
x = myAtomic;) gfx-rs/wgpu#9262. (affects
solari)

## Testing

- [x] 3d_scene
- [x] solari with dlss

## Showcase

#### 3d_scene on macos

<img width="1728" height="1084" alt="image"
src="https://github.com/user-attachments/assets/5ce80506-6924-4359-b469-92c32f06a505"
/>

#### ssao on macos

<img width="1728" height="1084" alt="image"
src="https://github.com/user-attachments/assets/8302ead7-54dc-44f9-8e71-a619d96c499e"
/>

#### bevy_city on macos

<img width="1728" height="1084" alt="image"
src="https://github.com/user-attachments/assets/4db1eba7-1c9b-4c54-95fe-1dc42ffc0e9e"
/>

#### Solari on Windows 11

<img width="1282" height="752" alt="image"
src="https://github.com/user-attachments/assets/2a367a06-f167-4b73-a781-6a2c5e4065dd"
/>
joelawm pushed a commit to joelawm/bevy that referenced this pull request Sep 8, 2026
# Objective

[Ray tracing on Metal](gfx-rs/wgpu#8071) has
been available since wgpu 29.

I shipped a PR to wgpu for [implementing bindless storage
buffers](gfx-rs/wgpu#9081) for metal, which was
released with wgpu 30. With the [wgpu 30
PR](bevyengine#24841) in bevy merged, we
are fully ready to add support to Solari on metal backends!

However because there is a limit of 31 buffer slots per shader stage.
Running Solari on main on a raytracing compatible Mac results in a
crash.

## Solution

I had combine the world cache into a single packed buffer. In theory
this should not introduce performance regressions since it’s only
reorganizing bindings and doesn’t introduce and copy or other passes.
Tried keeping the diff fairly minimal and easy to review.

Getting the buffer layout for the world cache on the CPU with
`ShaderType` was tricky. To avoid blowing up memory I put it in a
private module so you can't construct it.

## Testing

- Ran the Solari example on mac

```
cargo run --example solari --features bevy_solari,https,free_camera
```

Currently this PR needs a benchmark against main to ensure there's no
perf regression. I could use some help with that!

---

## Showcase

<img width="2566" height="1514" alt="shot"
src="https://github.com/user-attachments/assets/691b9bd3-129f-47e6-8efe-313cbadd6ff5"
/>

## Known limitations

Tracing spans incorrectly report 0.0ms , tracking in
gfx-rs/wgpu#9414

No denoising support yet. Could theoretically use [MetalFX Ray
Reconstruction](https://crates.io/crates/objc2-metal-fx) in place of
DLSS for cross-platform denoising support in Solari. In the longer term
we are also looking at Open Image Denoise 3.0 that promises temporal
denoising support.

---------

Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com>
sphw added a commit to metor-io/metor that referenced this pull request Oct 19, 2026
* build(panel): move gpui to upstream Zed at 56934ec

crates.io gpui stopped at 0.2.2, so take gpui and the new gpui_platform
crate from zed-industries/zed at a pinned rev, patch crates.io gpui to the
same rev so the facet fork's impls land on one gpui, and copy the Zed
patches (async-task, calloop, khronos-egl) that gpui's graph needs.

Port the panel to the new API: gpui_platform::application(), focus/blur
taking App, AsyncApp::update returning values directly, background
executor timers, ShapedLine::paint alignment, paint_image image bounds,
flex_grow_1, track_scroll by reference, Point-valued max_offset, Anchor,
Menu builders, BoxShadow::inset and KeyDownEvent::prefer_character_input.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* build(panel): enable gpui stacker, use upstream reqwest

gpui made stacker opt-in; turn it on to keep the stack growth 0.2.1 had
unconditionally. Upstream gpui no longer depends on reqwest, so the
zed-reqwest fork no longer shares a build with anything; use crates.io
reqwest 0.12 with the same features.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* build(panel): move to wgpu 30 and Bevy 5036d97

Bevy main moved to crates.io wgpu 30 in bevyengine/bevy#24841; pin its
merge commit, the smallest jump from 5330b01. Bevy now uses glam 0.33,
so the panel follows. Bevy boxes RenderCreation::Manual's resources.

wgpu 30 makes BufferSlice::get_mapped_range fallible, so a plot readback
whose staging buffer never mapped skips the frame instead of panicking,
and RequestAdapterOptions grows apply_limit_buckets (off: the panel
exposes no adapter to untrusted content).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs(panel): how wgpu, Bevy and gpui's wgpu are pinned

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Rendering Drawing game state to the screen D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants