bevyengine/bevy · critical

Texture format is not supported by the pipeline

Error message

Texture format is not supported by the pipeline

What it means

`MeshPipelineKey::from_target_format` (crates/bevy_pbr/src/render/mesh.rs:3168) encodes the view's color target format into a 5-bit field of the pipeline key using `texture_format_to_code` (crates/bevy_render/src/view/mod.rs:106). That function only maps WebGPU 'plain' renderable+blendable formats (R8/Rg8/Rgba8 unorm/snorm/srgb, Bgra8 variants, R16/Rg16/Rgba16 float+unorm+snorm, R32Float/Rg32Float/Rgba32Float, Rgb10a2Unorm, Rg11b10Ufloat). Any other format returns `None` and the `.expect` panics.

Source

Thrown at crates/bevy_pbr/src/render/mesh.rs:3169

    const SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS: u64 =
        Self::VIEW_PROJECTION_MASK_BITS.count_ones() as u64 + Self::VIEW_PROJECTION_SHIFT_BITS;

    const COLOR_TARGET_FORMAT_MASK_BITS: u64 = view::COLOR_TARGET_FORMAT_MASK_BITS as u64;
    const COLOR_TARGET_FORMAT_SHIFT_BITS: u64 = Self::SCREEN_SPACE_SPECULAR_TRANSMISSION_MASK_BITS
        .count_ones() as u64
        + Self::SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS;

    pub fn from_msaa_samples(msaa_samples: u32) -> Self {
        let msaa_bits =
            (msaa_samples.trailing_zeros() as u64 & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS;
        Self::from_bits_retain(msaa_bits)
    }

    /// Create a pipeline key from the view's color target format.
    #[inline]
    pub fn from_target_format(format: TextureFormat) -> Self {
        let code = texture_format_to_code(format)
            .expect("Texture format is not supported by the pipeline") as u64;
        Self::from_bits_retain(
            (code & Self::COLOR_TARGET_FORMAT_MASK_BITS) << Self::COLOR_TARGET_FORMAT_SHIFT_BITS,
        )
    }

    /// Color target format of the main pass for this pipeline key.
    #[inline]
    pub fn target_format(&self) -> TextureFormat {
        let code = ((self.bits() >> Self::COLOR_TARGET_FORMAT_SHIFT_BITS)
            & Self::COLOR_TARGET_FORMAT_MASK_BITS) as u8;
        texture_format_from_code(code)
            .expect("Unknown bits in `COLOR_TARGET_FORMAT_MASK_BITS` of the pipeline key")
    }

    pub fn msaa_samples(&self) -> u32 {
        1 << ((self.bits() >> Self::MSAA_SHIFT_BITS) & Self::MSAA_MASK_BITS)
    }

View on GitHub (pinned to 227d3a6c66)

Solutions

  1. Switch the camera's render target to a supported format: Rgba16Float for HDR, Bgra8UnormSrgb (default swapchain) for LDR
  2. Keep special-format buffers out of the main camera target: render the scene to a supported intermediate texture, then copy/resolve into the special-format texture in a custom pass
  3. Before assigning a target format, assert `bevy_render::view::texture_format_to_code(format).is_some()`

Example fix

// before: integer format as the main camera target -> panic in from_target_format
image.texture_descriptor.format = TextureFormat::Rgba32Uint; // picking buffer

// after: scene renders to a supported format; blit to the picking buffer separately
image.texture_descriptor.format = TextureFormat::Rgba16Float;
// ... then copy into the Rgba32Uint texture from a dedicated render node
Defensive patterns

Strategy: validation

Validate before calling

use bevy_render::view::texture_format_to_code;

fn assert_camera_format_supported(format: TextureFormat) {
    assert!(
        texture_format_to_code(format).is_some(),
        "format {format:?} is not encodable in MeshPipelineKey; \
         use a plain renderable+blendable format (e.g. Rgba16Float)"
    );
}

Prevention

When it happens

Trigger: Rendering a 3D camera whose color target uses a format outside that list: `TextureFormat::Rgba32Uint`, `Rgba8Uint`, `Rgb10a2Uint`, `Rg16Uint`, `Rgb9e5Ufloat`, 64-bit formats, or block-compressed formats — e.g. `Camera { target: RenderTarget::Texture(handle) }` pointing at an ID/picking buffer. Also triggered by manually calling `MeshPipelineKey::from_target_format` with such a format.

Common situations: Offscreen targets for mouse picking or object-ID passes written directly as the Camera output; data textures reused as render targets; post-processing setups that chose an integer or 64-bit format for precision without checking the mesh pipeline's supported set.

Related errors


AI-assisted analysis of bevyengine/bevy@227d3a6c66 (2026-08-20). Data as JSON: /api/errors/60db41fe3803440c. Report an issue: GitHub.