gfx-rs/wgpu · error

multi-plane textures are not supported

Error message

multi-plane textures are not supported

What it means

This panic is raised in the WebGPU (browser) backend when a texture aspect of Plane0, Plane1, or Plane2 is requested. Multi-plane (planar) texture formats, used e.g. by YUV video frames, have no equivalent in the browser's WebGPU API surface exposed to this backend, so the mapping from wgpu's TextureAspect to GpuTextureAspect cannot be performed. The library panics instead of returning an error because the request is fundamentally unsupported on this backend.

Source

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

        crate::ExternalImageSource::OffscreenCanvas(offscreen_canvas) => {
            webgpu_sys::GpuCopyExternalImageSourceInfo::new_with_offscreen_canvas(offscreen_canvas)
        }
        crate::ExternalImageSource::VideoFrame(video_frame) => {
            webgpu_sys::GpuCopyExternalImageSourceInfo::new_with_video_frame(video_frame)
        }
    };
    mapped.set_origin_gpu_origin_2d_dict(&map_origin_2d(view.origin));
    mapped.set_flip_y(view.flip_y);
    mapped
}

fn map_texture_aspect(aspect: wgt::TextureAspect) -> webgpu_sys::GpuTextureAspect {
    match aspect {
        wgt::TextureAspect::All => webgpu_sys::GpuTextureAspect::All,
        wgt::TextureAspect::StencilOnly => webgpu_sys::GpuTextureAspect::StencilOnly,
        wgt::TextureAspect::DepthOnly => webgpu_sys::GpuTextureAspect::DepthOnly,
        wgt::TextureAspect::Plane0 | wgt::TextureAspect::Plane1 | wgt::TextureAspect::Plane2 => {
            panic!("multi-plane textures are not supported")
        }
    }
}

fn map_component_swizzle(swizzle: wgt::ComponentSwizzle) -> char {
    match swizzle {
        wgt::ComponentSwizzle::Zero => '0',
        wgt::ComponentSwizzle::One => '1',
        wgt::ComponentSwizzle::R => 'r',
        wgt::ComponentSwizzle::G => 'g',
        wgt::ComponentSwizzle::B => 'b',
        wgt::ComponentSwizzle::A => 'a',
    }
}
fn map_texture_component_swizzle(
    swizzle: wgt::TextureComponentSwizzle,
) -> arrayvec::ArrayString<4> {
    let mut s = arrayvec::ArrayString::new();

View on GitHub (pinned to 3e11ff59bf)

Solutions

  1. Use TextureAspect::All, DepthOnly, or StencilOnly instead of a plane aspect on the web backend.
  2. Convert planar (YUV) data to a single-plane RGBA format on the CPU or via a shader before uploading on web.
  3. Gate plane-aspect usage behind a runtime backend check so it only runs on native backends.

Example fix

// before
let view = texture.create_view(&wgpu::TextureViewDescriptor { aspect: wgpu::TextureAspect::Plane0, ..Default::default() });
// after
let aspect = if cfg!(target_arch = "wasm32") { wgpu::TextureAspect::All } else { wgpu::TextureAspect::Plane0 };
let view = texture.create_view(&wgpu::TextureViewDescriptor { aspect, ..Default::default() });
Defensive patterns

Strategy: validation

Validate before calling

// before creating the view/copy
assert!(!matches!(aspect, wgpu::TextureAspect::Plane0 | wgpu::TextureAspect::Plane1 | wgpu::TextureAspect::Plane2), "plane aspects unsupported on web backend");

Type guard

fn is_web_safe_aspect(a: wgpu::TextureAspect) -> bool {
    matches!(a, wgpu::TextureAspect::All | wgpu::TextureAspect::DepthOnly | wgpu::TextureAspect::StencilOnly)
}

Prevention

When it happens

Trigger: Creating a texture view with aspect: TextureAspect::Plane0/Plane1/Plane2, or performing a copy whose view maps such an aspect (map_texture_copy_view, map_tagged_texture_copy_view, or create_view) on the web backend.

Common situations: Porting native wgpu code that decodes video or uses NV12/I420 planar formats to WASM/browser; sharing code that samples separate depth/stencil/planar aspects across backends; accidentally setting Plane0 as default in shared config code.

Related errors


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