gfx-rs/wgpu · error

MESH_SHADER feature must be enabled to call create_mesh_pipe

Error message

MESH_SHADER feature must be enabled to call create_mesh_pipeline

What it means

create_mesh_pipeline is unconditionally unimplemented in the web backend: any call panics stating the MESH_SHADER feature must be enabled. Browser WebGPU has no mesh-shader pipeline support, so the entry point exists only to satisfy the trait and can never succeed on this backend.

Source

Thrown at wgpu/src/backend/webgpu.rs:2504

        mapped_desc.set_multisample(&mapped_multisample);

        let mapped_primitive = map_primitive_state(&desc.primitive);
        mapped_desc.set_primitive(&mapped_primitive);

        let render_pipeline = self.inner.create_render_pipeline(&mapped_desc).unwrap();

        WebRenderPipeline {
            inner: render_pipeline,
            ident: crate::cmp::Identifier::create(),
        }
        .into()
    }

    fn create_mesh_pipeline(
        &self,
        _desc: &crate::MeshPipelineDescriptor<'_>,
    ) -> dispatch::DispatchRenderPipeline {
        panic!("MESH_SHADER feature must be enabled to call create_mesh_pipeline")
    }

    fn create_compute_pipeline(
        &self,
        desc: &crate::ComputePipelineDescriptor<'_>,
    ) -> dispatch::DispatchComputePipeline {
        let shader_module = desc.module.inner.as_webgpu();
        let mapped_compute_stage = webgpu_sys::GpuProgrammableStage::new(&shader_module.module);
        insert_constants_map(&mapped_compute_stage, desc.compilation_options.constants);
        if let Some(ep) = desc.entry_point {
            mapped_compute_stage.set_entry_point(ep);
        }
        let mapped_desc = match desc.layout {
            Some(layout) => webgpu_sys::GpuComputePipelineDescriptor::new(
                &layout.inner.as_webgpu().inner,
                &mapped_compute_stage,
            ),
            None => webgpu_sys::GpuComputePipelineDescriptor::new_with_gpu_auto_layout_mode(

View on GitHub (pinned to 3e11ff59bf)

Solutions

  1. Check whether the backend supports mesh shaders (e.g. adapter features / cfg!(target_arch = "wasm32")) before creating a mesh pipeline, and fall back to a vertex/fragment pipeline on web.
  2. Keep mesh-shader paths behind a feature flag disabled for wasm builds.
  3. Implement a traditional vertex-buffer-based equivalent pipeline for web targets.

Example fix

// before
let pipeline = device.create_mesh_pipeline(&mesh_desc); // panics on web
// after
let pipeline = if cfg!(target_arch = "wasm32") { device.create_render_pipeline(&vert_frag_desc) } else { device.create_mesh_pipeline(&mesh_desc) };
Defensive patterns

Strategy: fallback

Validate before calling

if cfg!(target_arch = "wasm32") {
    return create_standard_render_pipeline(...); // mesh pipelines never available on web
}

Type guard

fn supports_mesh_pipelines(backend_is_web: bool) -> bool {
    !backend_is_web
}

Prevention

When it happens

Trigger: Calling device.create_mesh_pipeline with any descriptor on the web (wasm32/browser) backend, regardless of requested features.

Common situations: Shared render-path code that builds mesh shader pipelines (task/mesh stages) on native (e.g. Vulkan/DX12) also running on web; feature detection missing before choosing a mesh-based render path.

Related errors


AI-assisted analysis of gfx-rs/wgpu@3e11ff59bf (2026-09-03). Data as JSON: /api/errors/dbb5b253d3068d86. Report an issue: GitHub.