Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
45fbacc
Wait did I break it
inner-daemons Aug 24, 2025
611c01a
More work
inner-daemons Aug 24, 2025
3d36680
Oops
inner-daemons Aug 24, 2025
c9c39fd
Another refactor
inner-daemons Aug 24, 2025
fb33028
Another slight refactor
inner-daemons Aug 24, 2025
ece1ea1
Another slight refactor
inner-daemons Aug 24, 2025
47c187b
Fixed it
inner-daemons Aug 24, 2025
8bc63b6
Worked a little more on trying to add it to example
inner-daemons Aug 24, 2025
55d6bf3
Fixed metal shader
inner-daemons Aug 24, 2025
edfd494
Fixed some passthrough stuff, now it runs (uggh)
inner-daemons Aug 24, 2025
6545fc3
Merge branch 'trunk' into mesh-shading/metal
inner-daemons Aug 24, 2025
d4725b1
Small update to test shader (still blank screen)
inner-daemons Aug 24, 2025
7efae60
Another quick update to the shader
inner-daemons Aug 24, 2025
bd79d51
Made mesh shader tests get skipped on metal due to not having MSL pas…
inner-daemons Aug 24, 2025
760de4b
Add changelog entry
inner-daemons Aug 24, 2025
3f56df6
Made some stuff more generic (bind groups & push constants)
inner-daemons Aug 24, 2025
d6931d2
Applied some fixes
inner-daemons Aug 24, 2025
43b8e70
Merge branch 'trunk' into mesh-shading/metal
inner-daemons Sep 1, 2025
091409b
Merge branch 'trunk' into mesh-shading/metal
inner-daemons Sep 15, 2025
7351903
Merge remote-tracking branch 'upstream/trunk' into mesh-shading/metal
inner-daemons Oct 11, 2025
86d1877
MESH SHADERS ON METAL LMAO HAHA YESS
inner-daemons Oct 11, 2025
00c19fc
Looked over all except command.rs
inner-daemons Oct 11, 2025
effe0f4
(Almost) everything passes 🎉
inner-daemons Oct 11, 2025
27d595e
Another quick fix (still 2 failing)
inner-daemons Oct 11, 2025
fb7e24c
Update changelog.md
inner-daemons Oct 11, 2025
233d76f
Added little bit to explain something
inner-daemons Oct 11, 2025
2d60810
More tiny incremental upgrades
inner-daemons Oct 11, 2025
204c542
Am I ... whatever its bedtime
inner-daemons Oct 11, 2025
7e6dee6
Did some work
inner-daemons Oct 11, 2025
5297afa
Merge branch 'trunk' into mesh-shading/metal
inner-daemons Oct 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ SamplerDescriptor {

- Texture now has `from_custom`. By @R-Cramer4 in [#8315](https://github.com/gfx-rs/wgpu/pull/8315).

#### Metal
- Add support for mesh shaders. By @SupaMaggie70Incorporated in [#8139](https://github.com/gfx-rs/wgpu/pull/8139)

### Bug Fixes

#### General
Expand Down
18 changes: 18 additions & 0 deletions examples/features/src/mesh_shader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ fn compile_hlsl(device: &wgpu::Device, entry: &str, stage_str: &str) -> wgpu::Sh
}
}

fn compile_msl(device: &wgpu::Device, entry: &str) -> wgpu::ShaderModule {
unsafe {
device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough {
entry_point: entry.to_owned(),
label: None,
msl: Some(std::borrow::Cow::Borrowed(include_str!("shader.metal"))),
num_workgroups: (1, 1, 1),
..Default::default()
})
}
}

pub struct Example {
pipeline: wgpu::RenderPipeline,
}
Expand All @@ -83,6 +95,12 @@ impl crate::framework::Example for Example {
compile_hlsl(device, "Mesh", "ms"),
compile_hlsl(device, "Frag", "ps"),
)
} else if adapter.get_info().backend == wgpu::Backend::Metal {
(
compile_msl(device, "taskShader"),
compile_msl(device, "meshShader"),
compile_msl(device, "fragShader"),
)
} else {
panic!("Example can only run on vulkan or dx12");
};
Expand Down
77 changes: 77 additions & 0 deletions examples/features/src/mesh_shader/shader.metal
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using namespace metal;

struct OutVertex {
float4 Position [[position]];
float4 Color [[user(locn0)]];
};

struct OutPrimitive {
float4 ColorMask [[flat]] [[user(locn1)]];
bool CullPrimitive [[primitive_culled]];
};

struct InVertex {
};

struct InPrimitive {
float4 ColorMask [[flat]] [[user(locn1)]];
};

struct FragmentIn {
float4 Color [[user(locn0)]];
float4 ColorMask [[flat]] [[user(locn1)]];
};

struct PayloadData {
float4 ColorMask;
bool Visible;
};

using Meshlet = metal::mesh<OutVertex, OutPrimitive, 3, 1, topology::triangle>;


constant float4 positions[3] = {
float4(0.0, 1.0, 0.0, 1.0),
float4(-1.0, -1.0, 0.0, 1.0),
float4(1.0, -1.0, 0.0, 1.0)
};

constant float4 colors[3] = {
float4(0.0, 1.0, 0.0, 1.0),
float4(0.0, 0.0, 1.0, 1.0),
float4(1.0, 0.0, 0.0, 1.0)
};


[[object]]
void taskShader(uint3 tid [[thread_position_in_grid]], object_data PayloadData &outPayload [[payload]], mesh_grid_properties grid) {
outPayload.ColorMask = float4(1.0, 1.0, 0.0, 1.0);
outPayload.Visible = true;
grid.set_threadgroups_per_grid(uint3(3, 1, 1));
}

[[mesh]]
void meshShader(
object_data PayloadData const& payload [[payload]],
Meshlet out
)
{
out.set_primitive_count(1);

for(int i = 0;i < 3;i++) {
OutVertex vert;
vert.Position = positions[i];
vert.Color = colors[i] * payload.ColorMask;
out.set_vertex(i, vert);
out.set_index(i, i);
}

OutPrimitive prim;
prim.ColorMask = float4(1.0, 0.0, 0.0, 1.0);
prim.CullPrimitive = !payload.Visible;
out.set_primitive(0, prim);
}

fragment float4 fragShader(FragmentIn data [[stage_in]]) {
return data.Color * data.ColorMask;
}
11 changes: 8 additions & 3 deletions wgpu-hal/src/metal/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,8 @@ impl super::PrivateCapabilities {
&& (device.supports_family(MTLGPUFamily::Apple7)
|| device.supports_family(MTLGPUFamily::Mac2)),
supports_shared_event: version.at_least((10, 14), (12, 0), os_is_mac),
mesh_shaders: device.supports_family(MTLGPUFamily::Apple7)
|| device.supports_family(MTLGPUFamily::Mac2),
}
}

Expand Down Expand Up @@ -1001,6 +1003,8 @@ impl super::PrivateCapabilities {
features.insert(F::SUBGROUP | F::SUBGROUP_BARRIER);
}

features.set(F::EXPERIMENTAL_MESH_SHADER, self.mesh_shaders);

features
}

Expand Down Expand Up @@ -1077,10 +1081,11 @@ impl super::PrivateCapabilities {
max_buffer_size: self.max_buffer_size,
max_non_sampler_bindings: u32::MAX,

max_task_workgroup_total_count: 0,
max_task_workgroups_per_dimension: 0,
// See https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf, Maximum threadgroups per mesh shader grid
max_task_workgroup_total_count: 1024,
max_task_workgroups_per_dimension: 1024,
max_mesh_multiview_count: 0,
max_mesh_output_layers: 0,
max_mesh_output_layers: self.max_texture_layers as u32,

max_blas_primitive_count: 0, // When added: 2^28 from https://developer.apple.com/documentation/metal/mtlaccelerationstructureusage/extendedlimits
max_blas_geometry_count: 0, // When added: 2^24
Expand Down
Loading