Skip to content

Conversation

@ChristopherBiscardi
Copy link
Contributor

@ChristopherBiscardi ChristopherBiscardi commented Dec 24, 2025

This is a working naga 28 update. I noticed some tests haven't passed (specifically cargo test --all-features) since before 0.14, so this PR doesn't attempt to make them pass.

enumerate_adaptors

instance.enumerate_adapters is async now (and available on webgpu): gfx-rs/wgpu#8230 . more details in the wgpu release notes.

ControlBarrier & MemoryBarrier

Barrier was split in two to support MemoryBarriers: gfx-rs/wgpu#7630

From the PR, it seems like falling back to ControlBarrier is fine so that's what I did.

Ray Query enable

ray queries require enable wgpu_ray_query;: gfx-rs/wgpu#8545

This doesn't currently seem to make it through, and the relevant test fails.

ImageAtomic

Image atomics were added in gfx-rs/wgpu#6706

Mesh Shaders

Mesh shaders are a major feature of wgpu 28, but I've set their fields to None here in the interest of doing an upgrade and not a feature add at the same time

https://github.com/gfx-rs/wgpu/releases/tag/v28.0.0

update: I found some time and built a wgpu mesh/task shader demo and used that to validate some of the mesh shader functionality. I've used this to successfully compile a task shader with naga-oil and run it, but there's still something missing from the mesh shader module output here.

@ChristopherBiscardi
Copy link
Contributor Author

oh actually, cargo test --all-features doesn't pass on master and hasn't even been able to compile since 0.15. 0.14 (7031ca1) fails the test in the same way.

I'm going to back up a bit and just get cargo test to work instead.

@ChristopherBiscardi
Copy link
Contributor Author

wgsl directive support was added in #123 and actually works for the ray queries, as long as the add_composable_module function is not used. (so a single file with all the content works)

This seems like a pattern solari actually uses at the moment, so I'm not modifying the test to make it pass, but #123 mentions that trying to make this work got complicated.

Other than that (and no actual implementation for mesh shaders) this seems like the v28 upgrade completed.

@ChristopherBiscardi
Copy link
Contributor Author

I was able to fix the rayquery test.

for composable modules, the enable extension needs to be below the #define_import_path like this:

#define_import_path test_module

enable wgpu_ray_query;

If it is not, the error will indicate that the extension is not enabled.

called Result::unwrap() on an Err value: ComposerError { inner: WgslParseError(ParseError { message: "the wgpu_ray_query enable extension is not enabled", labels: [(Span { start: 67, end: 89 }, "the wgpu_ray_query "Enable Extension" is needed for this functionality, but it is not currently enabled.")], notes: ["You can enable this extension by adding enable wgpu_ray_query; at the top of the shader, before any other items."] }), source: Module { name: "test_module", offset: 0, defs: {} } }

@ChristopherBiscardi ChristopherBiscardi changed the title start of naga 28 update naga 28 update Dec 24, 2025
@robtfm
Copy link
Collaborator

robtfm commented Jan 16, 2026

i think image atomic support should be added before releasing, people are probably using this already.
it shouldn't be difficult - i can try if you want.

sorry i see this is only in prune, not necessary then.

@robtfm
Copy link
Collaborator

robtfm commented Jan 19, 2026

doesn't build on windows, seems to be conflicting versions of the windows crate.

first error of many:

error[E0308]: mismatched types
   --> [...]\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\wgpu-hal-28.0.0\src\dx12\suballocation.rs:83:71
    |
 83 | ...ice: gpu_allocator::d3d12::ID3D12DeviceVersion::Device(raw.clone()),        
    |         ------------------------------------------------- ^^^^^^^^^^^ expected `ID3D12Device`, found `Direct3D12::ID3D12Device`
    |         |
    |         arguments to this enum variant are incorrect
    |
note: there are multiple different versions of crate `windows` in the dependency graph

cargo tree -i [email protected]:

windows v0.58.0
└── gpu-allocator v0.28.0
    └── wgpu-hal v28.0.0
        ├── wgpu v28.0.0
        │   [dev-dependencies]
        │   └── naga_oil v0.21.0 (C:\Users\robfm\Documents\gamedev\lno\naga_oil)
        ├── wgpu-core v28.0.0
        │   └── wgpu v28.0.0 (*)
        └── wgpu-core-deps-windows-linux-android v28.0.0
            └── wgpu-core v28.0.0 (*)

cargo tree -i [email protected]:

windows v0.62.2
└── wgpu-hal v28.0.0
    ├── wgpu v28.0.0
    │   [dev-dependencies]
    │   └── naga_oil v0.21.0 (C:\Users\robfm\Documents\gamedev\lno\naga_oil)
    ├── wgpu-core v28.0.0
    │   └── wgpu v28.0.0 (*)
    └── wgpu-core-deps-windows-linux-android v28.0.0
        └── wgpu-core v28.0.0 (*)

@robtfm
Copy link
Collaborator

robtfm commented Jan 19, 2026

cargo update fixed it... my bad

@robtfm
Copy link
Collaborator

robtfm commented Jan 19, 2026

for the wgpu_ray_query extension issue, the solution is to add the enable directive to both the module that uses it, and the top level module it's included from. this makes sense when you consider how naga oil works, it builds each module in isolation first (so it requires the directive for the module), then generates a single shader from the top containing all the includes (so it requires the directive for the top-level shader).

if we accept that as the way to do it, we don't need the extra feature.

@ChristopherBiscardi
Copy link
Contributor Author

for the wgpu_ray_query extension issue, the solution is to add the enable directive to both the module that uses it, and the top level module it's included from. this makes sense when you consider how naga oil works, it builds each module in isolation first (so it requires the directive for the module), then generates a single shader from the top containing all the includes (so it requires the directive for the top-level shader).

if we accept that as the way to do it, we don't need the extra feature.

This works for the test, but doesn't work in practice when considering solari's real-world usage.

@robtfm
Copy link
Collaborator

robtfm commented Jan 19, 2026

Can you link it pls

@ChristopherBiscardi
Copy link
Contributor Author

bevyengine/bevy#22265 under the "old explanations" for solari's enable-related issue.

In composable modules, if we put the wgsl directive before the declare it gets stripped out, and if we put it after it seems like it ends up in the final file causing other issues.

The flag is only meant as a temporary measure, since Bevy seems to be moving to wesl and this unblocks wgpu 28 by not breaking solari on ray query capable devices.

value,
},
_,
) => todo!(),
Copy link

Choose a reason for hiding this comment

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

why todo?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • The tests for this module do not pass and have not passed since at least 0.14
  • It is undocumented according to the README
  • It is behind a non-default feature flag

As far as I'm aware, "todo" is the state of the module itself, not just these snippets.

Copy link

@superdump superdump left a comment

Choose a reason for hiding this comment

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

If the tests that did pass still pass, and examples and bevy work on top of it then looks ok to me.

@robtfm do you want to finish a review?

@robtfm
Copy link
Collaborator

robtfm commented Jan 22, 2026

i made a pr to your branches (here and on the bevy wgpu pr) to make the directives work properly.

it has a couple caveats:

  • enable wgpu_ray_query has to be first (above #define_import_path or #import ... or anything else)
  • the directive has to be enabled for all modules including the code that needs it, e,g. if a imports b and b imports c and c uses a directive, it must be enabled in a, b and c

but it avoids the feature and works for all the extensions (wgpu_mesh_shader, wgpu_ray_query, wgpu_ray_query_vertex_return, dual_source_blending, f16, clip_distances, plus any they add in future)

@ChristopherBiscardi
Copy link
Contributor Author

confirmed solari working in the bevy repo with the flag removal. (Happy to have the flag gone)

image

@robtfm robtfm merged commit e349f54 into bevyengine:master Jan 22, 2026
7 checks passed
github-merge-queue bot pushed a commit to bevyengine/bevy that referenced this pull request Jan 22, 2026
Upgrade to wgpu 28

> [!important]
> This can't merge until bevyengine/naga_oil#132
does, and the dependency is updated from my fork to the release.
> 
> Also requires wgpu 28 in dlss_wgpu:
bevyengine/dlss_wgpu#17

> [!note]
> This does not enable mesh shaders, and neither does the naga_oil PR. I
chose to do an upgrade first, then go back and see about mesh shaders.

Here's a general list of changes and what I did. Commits are grouped by
feature except for the last one, which enabled solari when I ran the
solari example.

## MipmapFilterMode is split from FilterMode

- Split MipmapFilterMode from FilterMode #8314:
gfx-rs/wgpu#8314

solution: implement From for `MipmapFilterMode`/`ImageFilterMode` since
the values are the same. The split was because the spec indicates they
are different types, even though they have the same values.

## Push Constants are now Immediates

- gfx-rs/wgpu#8724

immediate_size is [a
u32](https://docs.rs/wgpu/28.0.0/wgpu/struct.PipelineLayoutDescriptor.html#structfield.immediate_size)
so use that instead of `PushConstantRange`

## Capabilities name changes

- gfx-rs/wgpu#8671

Got new list from
https://github.com/gfx-rs/wgpu/blob/trunk/wgpu-core/src/device/mod.rs#L449
and copied it in.

## subgroup_{min,max}_size moved from Limits to AdapterInfo

- gfx-rs/wgpu#8609

Update the limits to have the fields they have now, mirror the logic
from the other limits calls.

## multiview_mask

- gfx-rs/wgpu#8206

set to None because we don't use it currently. Its vaguely for VR.

## error scope is now a guard

- gfx-rs/wgpu#8685

retain guard and then pop() it later


---

I made one mistake during the PR, thinking set_immediates was going to
be the size of the immediates and not the offset. I'd like reviewers to
take a look at immediates offset and size sites specifically just in
case I missed something.

Here's a bunch of examples running

<img width="1470" height="1040" alt="screenshot-2025-12-24-at-16 47
22@2x"
src="https://github.com/user-attachments/assets/83dcf4c8-69f5-480a-b724-86598530f25a"
/>
<img width="1470" height="1040" alt="screenshot-2025-12-24-at-16 48
44@2x"
src="https://github.com/user-attachments/assets/46d897fa-1ab2-44ef-8055-fe2fce740dbc"
/>
<img width="1470" height="1040" alt="screenshot-2025-12-24-at-16 49
10@2x"
src="https://github.com/user-attachments/assets/6ae7a9bf-0473-4800-8dfc-233a6a41d6df"
/>
<img width="1470" height="1040" alt="screenshot-2025-12-24-at-16 49
31@2x"
src="https://github.com/user-attachments/assets/89f84a26-cfbd-4196-bca8-111c3d20ba7b"
/>


## Known Issues

> [!NOTE]
> 
> There are no current known issues. Everything previous has been
solved.

- [x] enable extensions can not be written in naga oil in a way that
allows them to be used in composed modules.

Update: this was fixed by introducing a flag in naga-oil to force
shaders to allow ray queries in composed modules when using bevy_solari.
This is temporary and will be different in WESL-future.

<details><summary>old explanation</summary>
This is blocking solari from working on nvidia (solari runs successfully
on macos m1) because it needs `enable wgpu_ray_query;`. Putting the
declaration before `#define_import_path` means it gets stripped out
(afaict), and putting it after results in

```
error: expected global declaration, but found a global directive
  ┌─ embedded://bevy_solari/scene/raytracing_scene_bindings.wgsl:3:1
  │
3 │ enable wgpu_ray_query;
  │ ^^^^^^ written after first global declaration
  │
  = expected global declaration, but found a global directive
```

</details>

- [x] dlss_wgpu mixes apis which [causes panics
now](bevyengine/dlss_wgpu#17 (comment)).

<details><summary>Previous notes as dlss_wgpu was being fixed
here</summary>

The wgpu release notes don't mention which PR this was introduced in,
only saying:

> Using both the wgpu command encoding APIs and
CommandEncoder::as_hal_mut on the same encoder will now result in a
panic.

It was caused by gfx-rs/wgpu#8373 which claimed
to not know of any use cases

> With record on finish, the actual ordering on the command buffer is
deeply counter intuitive (all as_hal would come first) and I think it
additionally was just flat out broken in some ways
> -
https://discord.com/channels/691052431525675048/743663924229963868/1453786307099758683

Possible path forward is using multiple command buffers:
https://discord.com/channels/691052431525675048/743663924229963868/1453795633503670415

</summary>

---------

Co-authored-by: robtfm <[email protected]>
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.

5 participants