Skip to content

Mesh shaders MSL writer#8739

Merged
cwfitzgerald merged 13 commits intogfx-rs:trunkfrom
inner-daemons:mesh-shading/msl-write
Apr 7, 2026
Merged

Mesh shaders MSL writer#8739
cwfitzgerald merged 13 commits intogfx-rs:trunkfrom
inner-daemons:mesh-shading/msl-write

Conversation

@inner-daemons
Copy link
Copy Markdown
Collaborator

@inner-daemons inner-daemons commented Dec 16, 2025

Connections
Works towards #7197
Depends on #9099

Description
Adds support for mesh shaders to MSL writer.

Also adds a limit.

Testing
Snapshots & examples & other tests

Squash or Rebase?
Squash

Checklist

  • Run cargo fmt.
  • Run taplo format.
  • Run cargo clippy --tests. If applicable, add:
    • --target wasm32-unknown-unknown
  • Run cargo xtask test to run tests.
  • If this contains user-facing changes, add a CHANGELOG.md entry.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds Metal Shading Language (MSL) writer support for mesh shaders, enabling WGSL mesh shaders to be automatically transpiled to MSL. This replaces the previous approach of using handwritten Metal shader files.

Changes:

  • Implements MSL code generation for task and mesh shader entry points with proper Metal 3.0 syntax
  • Refactors mesh shader detection into a shared uses_mesh_shaders() function used across multiple backends
  • Enables Metal as a target backend for mesh shader tests and examples

Reviewed changes

Copilot reviewed 14 out of 19 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/tests/wgpu-gpu/mesh_shader/shader.metal Deleted handwritten Metal shader, replaced with auto-generated code
tests/tests/wgpu-gpu/mesh_shader/mod.rs Removed compile_msl function, now uses WGSL compilation for Metal backend
naga/tests/out/msl/wgsl-policy-mix.msl Fixed ordering of private variable initialization before workgroup barrier
naga/tests/out/msl/wgsl-mesh-shader*.msl New generated MSL output files for mesh shader tests
naga/tests/in/wgsl/mesh-shader*.toml Added Metal as target and MSL version 3.0 requirement
naga/src/proc/mod.rs Added uses_mesh_shaders() utility function for detecting mesh shader usage
naga/src/back/wgsl/writer.rs Refactored to use new uses_mesh_shaders() function
naga/src/back/spv/writer.rs Refactored mesh shader checking, moved logic to use shared function
naga/src/back/spv/mesh_shader.rs Removed require_mesh_shaders() helper, consolidated into writer
naga/src/back/msl/writer.rs Main implementation of mesh shader MSL code generation
naga/src/back/msl/mod.rs Added Payload binding type, MeshOutput location mode, and UnsupportedMeshShader error
examples/features/src/mesh_shader/shader.metal Deleted handwritten Metal shader
examples/features/src/mesh_shader/mod.rs Removed compile_msl function, now uses WGSL for Metal

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

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

Soooooooome comments

@inner-daemons
Copy link
Copy Markdown
Collaborator Author

@cwfitzgerald Thanks for the review, will get to it today. I didn't make it fully clear, but when you reviewed this PR many parts were derived from #8756 which is designed to land before this and the HLSL PR. I've moved all changes from all 3 PRs that could could conflict into that PR and then back here. So thats why there are some changes related to spv

@inner-daemons
Copy link
Copy Markdown
Collaborator Author

Alright, I've cleaned this up a tiny bit, since I had left some changes from the SPV fixes PR.

Copy link
Copy Markdown
Member

@Wumpf Wumpf left a comment

Choose a reason for hiding this comment

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

frankly, changes to msl/writer.rs are just a nightmare to review. The file is so insanely large, even with an agent I can hardly make sense of it. As so often it seems this is no individual's fault, but we have to make sure it gets better, so anything we can do to improve readability & maintainability we have to do. I believe a lof of the steps could be factored more cleanly

Importantly, the outputs of the test shaders look good I believe, so I think after a little bit of polish we can move forward with this.

@inner-daemons inner-daemons requested a review from Wumpf March 9, 2026 20:34
@inner-daemons
Copy link
Copy Markdown
Collaborator Author

@Wumpf Mostly addressed

@inner-daemons inner-daemons force-pushed the mesh-shading/msl-write branch from 698ba38 to a1fe019 Compare March 10, 2026 21:35
@cwfitzgerald cwfitzgerald removed their assignment Mar 11, 2026
Copy link
Copy Markdown
Contributor

@ChristopherBiscardi ChristopherBiscardi left a comment

Choose a reason for hiding this comment

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

While unfamiliar with a few of the intricacies of wgpu here, I have reviewed the code and not found anything obviously wrong.

Probably more interestingly, I ported Bevy to use this PR to run a couple of examples I've been working on using the current release's wgsl/vulkan support. The examples run as expected with no wgsl changes, using the wgsl I wrote targeting vulkan platforms, with this PR on an m1 max.

One example here is a visualization of a single task shader dispatching vec3u(u32(globals.time)) mesh shaders that draw a single cube at their grid position.

screenshot-2026-03-11-at-20.51.57-converted.mp4

The other is an in-progress version of this grass, which doesn't currently use task shaders.

screenshot-2026-03-11-at-20.54.34-converted.mp4

So this PR works as expected as far as my demo code/bevy is concerned.

Copy link
Copy Markdown
Member

@Wumpf Wumpf left a comment

Choose a reason for hiding this comment

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

the extra barriers outside of mesh shaders worry me a bit, otherwise I believe this is good now

@caelunshun
Copy link
Copy Markdown
Contributor

caelunshun commented Mar 28, 2026

I've noticed that if my mesh shader outputs vertex data with the @builtin(clip_distance) attribute, I get a shader translation error:

Error log

Shader translation error for stage ShaderStages(MESH): Metal: program_source:195:51: warning: unused variable 'plane' [-Wunused-variable]
            package_shared_clipping_ClippingPlane plane = window.planes.inner[metal::min(unsigned(_e10), 4u)];
                                                  ^
program_source:212:32: error: 'clip_distance' attribute cannot be applied to types
    float clip_distances [5] [[clip_distance]];
                               ^
program_source:307:95: error: invalid type 'ms_mainVertexOutput' for mesh vertex type
  metal::mesh<ms_mainVertexOutput, ms_mainPrimitiveOutput, 64, 32, metal::topology::triangle> meshOutput
                                                                                              ^
program_source:307:95: note: in instantiation of template class 'metal::mesh<ms_mainVertexOutput, ms_mainPrimitiveOutput, 64, 32, metal::topology::triangle>' requested here
program_source:212:5: note: field of illegal type 'float[5]' declared here
    float clip_distances [5] [[clip_distance]];

Not sure if this is an inherent limitation or a bug in the shader translator. Let me know if making a minimal reproduction shader would help.

(This seems to work fine on the Vulkan backend.)

@inner-daemons
Copy link
Copy Markdown
Collaborator Author

@caelunshun Definitely a bug! I'd rather not block this PR any longer so if you file an issue I'll fix that and add testing in another PR. Appreciate the report!

@inner-daemons
Copy link
Copy Markdown
Collaborator Author

inner-daemons commented Mar 30, 2026

@Wumpf Can we please merge this soon? Every time theres a new review new stuff has been added and the diffs are gross. This PR is big enough that updating it every time is a huge hassle, and also comes with new issues. Like the clip distances thing, which was added a week or two ago and I guess conflicts, because this PR completely changes how input arguments are written. Then there's always something broken on DX12 which I have to wait for the CI with 4 thigns running at once to catch. Fix it. Wait another hour.

Can we keep any smaller issues to followup PRs. I have zero interest in continuing to maintain this much longer.

# Conflicts:
#	CHANGELOG.md
#	naga/src/back/msl/mod.rs
#	naga/src/back/msl/writer.rs
#	wgpu-core/src/command/bundle.rs
#	wgpu-core/src/command/render.rs
@inner-daemons
Copy link
Copy Markdown
Collaborator Author

@Wumpf or @cwfitzgerald, if this is good to go, should we turn on automerge?

@cwfitzgerald cwfitzgerald enabled auto-merge (squash) April 7, 2026 17:23
@cwfitzgerald cwfitzgerald merged commit b5bd5ae into gfx-rs:trunk Apr 7, 2026
94 of 95 checks passed
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.

6 participants