gfx-rs/wgpu · error
the plane must be specified for multi-planar formats
Error message
the plane must be specified for multi-planar formats
What it means
`TextureFormat::subsampling_factors` requires an explicit plane index (`Some(n)`) for multi-planar formats like NV12 and P010, since subsampling differs per plane. Calling it with `None` on such a format panics because the question is unanswerable without knowing which plane.
Source
Thrown at wgpu-types/src/texture/format.rs:548
/// 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));
/// // ... but it has a red channel ...View on GitHub (pinned to 3e11ff59bf)
Solutions
- Pass `Some(0)` or `Some(1)` explicitly when the format is NV12/P010
- Branch on `format.is_multi_planar()` (or match the format) before choosing None vs Some
- Fix the helper to accept a plane parameter and require it for multi-planar formats
Example fix
// before let (fx, fy) = nv12_format.subsampling_factors(None); // panics // after let (fx, fy) = nv12_format.subsampling_factors(Some(0)); // luma plane
Defensive patterns
Strategy: validation
Validate before calling
fn subsampling(format: wgpu::TextureFormat, plane: u32) -> (u32, u32) {
if format.plane_count() > 1 { format.subsampling_factors(Some(plane)) }
else { format.subsampling_factors(None) }
} Prevention
- Pass Some(plane) whenever the format is multi-planar; pass None only for single-planar formats
- Write generic texture helpers to take the format and resolve plane handling internally
- Unit-test helpers against NV12/P010 as well as RGBA formats
When it happens
Trigger: Calling `format.subsampling_factors(None)` where format is NV12 or P010 — e.g. generic code that always passes None because it was written for single-planar formats (rgba8unorm etc.).
Common situations: Shared texture-size/copy helpers written before multi-planar formats existed; passing through an Option from caller code that doesn't know the format is multi-planar; porting code from APIs where plane defaults to 0.
Related errors
- plane {plane} is not valid for {self:?}
- 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/d24ee45dfe28bb90.
Report an issue: GitHub.