gfx-rs/wgpu · error
plane {plane} is not valid for {self:?}
Error message
plane {plane} is not valid for {self:?} What it means
`TextureFormat::subsampling_factors(plane)` returns the chroma subsampling factor for a given plane index. For multi-planar formats (NV12, P010) only planes 0 and 1 exist; requesting any other plane index panics with this message because there is no defined subsampling for it.
Source
Thrown at wgpu-types/src/texture/format.rs:547
/// Returns the number of planes a multi-planar format has.
#[must_use]
pub fn planes(&self) -> Option<u32> {
match *self {
Self::NV12 => Some(2),
Self::P010 => Some(2),
_ => None,
}
}
/// Returns the subsampling factor for the indicated plane of a multi-planar format.
#[must_use]
pub fn subsampling_factors(&self, plane: Option<u32>) -> (u32, u32) {
match *self {
Self::NV12 | Self::P010 => match plane {
Some(0) => (1, 1),
Some(1) => (2, 2),
Some(plane) => unreachable!("plane {plane} is not valid for {self:?}"),
None => unreachable!("the plane must be specified for multi-planar formats"),
},
_ => (1, 1),
}
}
/// Returns a [TextureChannel] with the bits set where the texture format contains
/// the respective channels.
///
/// # Example
/// ```rust
/// # use wgpu_types::{TextureFormat, TextureChannel};
///
/// // `Rgba` has a `red`, `green`, `blue` and `alpha` channel!
/// assert!(TextureFormat::Rgba8Unorm.channels().contains(TextureChannel::RGBA));
///
/// // `Rg` hasn't got an alpha channel...
/// assert!(!TextureFormat::Rg8Unorm.channels().contains(TextureChannel::ALPHA));View on GitHub (pinned to 3e11ff59bf)
Solutions
- Only request planes 0 or 1 for NV12/P010 — derive the loop bound from `format.plane_count()`
- For non-multi-planar formats pass `None`, which returns (1,1)
- Add a bounds check or match on the format before querying plane-specific properties
Example fix
// before
for plane in 0..3 {
let (fx, fy) = format.subsampling_factors(Some(plane));
}
// after
for plane in 0..format.plane_count() {
let (fx, fy) = format.subsampling_factors(Some(plane as u32));
} Defensive patterns
Strategy: validation
Validate before calling
fn valid_plane(format: wgpu::TextureFormat, plane: u32) -> bool {
plane < format.plane_count() as u32
} Type guard
fn plane_in_range(format: wgpu::TextureFormat, plane: u32) -> Option<u32> {
(plane < format.plane_count() as u32).then_some(plane)
} Prevention
- Derive plane loop bounds from format.plane_count(), never hardcode
- Remember NV12/P010 have exactly 2 planes
- Centralize per-plane property queries in one helper that validates the index
When it happens
Trigger: Calling `format.subsampling_factors(Some(n))` where format is NV12 or P010 and n >= 2 (e.g. iterating planes 0..format.plane_count() incorrectly, or hardcoding plane indices).
Common situations: Video decode/encode pipelines iterating planes with a wrong count; copying code between single-planar and multi-planar handling; misreading plane_count for NV12/P010 (which is 2).
Related errors
- the plane must be specified for multi-planar formats
- wgpu error: {err}
- Mismatched pop_error_scope call: no error scope for this thr
- Mismatched pop_error_scope call: error scopes must be popped
- Feature `MESH_SHADING` not enabled
AI-assisted analysis of gfx-rs/wgpu@3e11ff59bf (2026-09-03).
Data as JSON: /api/errors/76dcf9de2bba3f1d.
Report an issue: GitHub.