gfx-rs/wgpu · error

MESH_SHADER feature must be enabled to call draw_mesh_tasks_

Error message

MESH_SHADER feature must be enabled to call draw_mesh_tasks_indirect

What it means

Mesh shader indirect draws are unsupported by the WebGPU backend, so RenderPassEncoder::draw_mesh_tasks_indirect panics unconditionally. This path requires MESH_SHADER (plus indirect support) on native backends.

Source

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

            .draw_indirect_with_f64(&buffer.inner, indirect_offset as f64);
    }

    fn draw_indexed_indirect(
        &mut self,
        indirect_buffer: &dispatch::DispatchBuffer,
        indirect_offset: crate::BufferAddress,
    ) {
        let buffer = indirect_buffer.as_webgpu();
        self.inner
            .draw_indexed_indirect_with_f64(&buffer.inner, indirect_offset as f64);
    }

    fn draw_mesh_tasks_indirect(
        &mut self,
        _indirect_buffer: &dispatch::DispatchBuffer,
        _indirect_offset: crate::BufferAddress,
    ) {
        panic!("MESH_SHADER feature must be enabled to call draw_mesh_tasks_indirect")
    }

    fn multi_draw_indirect(
        &mut self,
        indirect_buffer: &dispatch::DispatchBuffer,
        indirect_offset: crate::BufferAddress,
        count: u32,
    ) {
        let buffer = indirect_buffer.as_webgpu();

        for i in 0..count {
            let offset = indirect_offset + i as crate::BufferAddress * 16;
            self.inner
                .draw_indirect_with_f64(&buffer.inner, offset as f64);
        }
    }

    fn multi_draw_indexed_indirect(

View on GitHub (pinned to 3e11ff59bf)

Solutions

  1. Gate the call on Features::MESH_SHADER and a non-WebGPU backend.
  2. Fall back to CPU-computed draw counts with regular draw calls.
  3. Use standard draw_indirect with a conventional pipeline as a fallback.
  4. Detect capabilities at device creation and pick a rendering strategy accordingly.

Example fix

// before
render_pass.draw_mesh_tasks_indirect(&count_buffer, 0);
// after
if mesh_shader_supported {
    render_pass.draw_mesh_tasks_indirect(&count_buffer, 0);
} else {
    render_pass.draw_indirect(&args_buffer, 0);
}
Defensive patterns

Strategy: validation

Validate before calling

if supports_mesh_shader(device.features(), backend) {
    render_pass.draw_mesh_tasks_indirect(&buf, 0);
} else { /* fallback draw path */ }

Type guard

fn supports_mesh_shader(f: Features, b: Backend) -> bool {
    f.contains(Features::MESH_SHADER) && b != Backend::Browser
}

Prevention

When it happens

Trigger: Calling draw_mesh_tasks_indirect(indirect_buffer, indirect_offset) on a render pass while running on the webgpu backend, or on a native backend without Features::MESH_SHADER.

Common situations: GPU-driven rendering issuing mesh task draws from buffers, compiled for web; shared indirect-draw helpers that don't distinguish mesh-task indirect draws; Vulkan prototypes moved to the browser backend.

Related errors


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