Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic whilst loading ktx2 file #9121

Closed
66OJ66 opened this issue Jul 11, 2023 · 3 comments · Fixed by #9158
Closed

Panic whilst loading ktx2 file #9121

66OJ66 opened this issue Jul 11, 2023 · 3 comments · Fixed by #9158
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior
Milestone

Comments

@66OJ66
Copy link
Contributor

66OJ66 commented Jul 11, 2023

Bevy version

v0.11.0

[Optional] Relevant system information

Rust 1.70
OS: openSUSE Tumbleweed

`AdapterInfo { name: "AMD Radeon RX 6600 XT (RADV NAVI23)", vendor: 4098, device: 29695, device_type: DiscreteGpu, driver: "radv", driver_info: "Mesa 23.1.2", backend: Vulkan }`

What went wrong

I attempted to load a ktx2 file which led to the following panic.

2023-07-11T22:23:24.829163Z ERROR wgpu::backend::direct: Handling wgpu errors as fatal by default    
thread 'Compute Task Pool (5)' panicked at 'wgpu error: Validation Error

Caused by:
    In Device::create_texture
    Texture format Astc { block: B4x4, channel: UnormSrgb } can't be used due to missing features.
    Features Features(TEXTURE_COMPRESSION_ASTC) are required but not enabled on the device

', /home/_/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-0.16.2/src/backend/direct.rs:3019:5

This file loaded without issue in Bevy v0.10.1 (and earlier) with these features enabled:

[dependencies]
bevy = { version = "0.10.1", features = ["ktx2", "zstd", "basis-universal"]}

Additional information

I've uploaded a basic example here: https://github.com/66OJ66/basis_universal_error_repo

The original PNG file was sourced from here: https://ambientcg.com/view?id=Ground037

I converted it to ktx2 using toktx (https://github.khronos.org/KTX-Software/ktxtools/toktx.html).
The exact command was:
toktx --encode uastc --zcmp 22 --genmipmap --uastc_rdo_l 0.5 {output} {input.png}

@66OJ66 66OJ66 added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Jul 11, 2023
@alice-i-cecile alice-i-cecile added A-Rendering Drawing game state to the screen and removed S-Needs-Triage This issue needs to be labelled labels Jul 11, 2023
@Elabajaba
Copy link
Contributor

Elabajaba commented Jul 12, 2023

I don't know how this worked previously, but the only desktop/laptop hardware that supported ASTC was Intel iGPUs, and they dropped support for it in recent hardware.

edit: I guess previously it was somehow autoconverting it with basis-universal stuff somehow?

edit2: It seems like #8336 is when the crashing started.

@66OJ66
Copy link
Contributor Author

66OJ66 commented Jul 12, 2023

edit2: It seems like #8336 is when the crashing started.

Yeah, I checked the original PR where compressed texture support was added, and this comment mentioned an potential issue with WebGPU: #3884 (comment)

@66OJ66
Copy link
Contributor Author

66OJ66 commented Jul 14, 2023

After investigating a bit more, this is caused by a combination of 2 issues:

  1. If the RenderDevice resource is missing when the ImageTextureLoader is initialised, it defaults to supporting all compressed textures (line 85)

    impl FromWorld for ImageTextureLoader {
    fn from_world(world: &mut World) -> Self {
    let supported_compressed_formats = match world.get_resource::<RenderDevice>() {
    Some(render_device) => CompressedImageFormats::from_features(render_device.features()),
    None => CompressedImageFormats::all(),
    };
    Self {
    supported_compressed_formats,
    }
    }
    }

  2. The RenderPlugin and ImagePlugin are added sequentially, but in Webgpu support #8336 the renderer initialisation was made async. As a result, now at the time of ImagePlugin initialisation the RenderDevice resource doesn't exist yet, triggering the fallback condition above

    #[cfg(feature = "bevy_render")]
    {
    group = group
    .add(bevy_render::RenderPlugin::default())
    // NOTE: Load this after renderer initialization so that it knows about the supported
    // compressed texture formats
    .add(bevy_render::texture::ImagePlugin::default());

So, fixing this should just be a case of delaying the ImageTextureLoader initalisation within ImagePlugin - I'll prepare a PR for this shortly

@nicopap nicopap added this to the 0.11.1 milestone Jul 17, 2023
github-merge-queue bot pushed a commit that referenced this issue Jul 23, 2023
# Objective

Fixes #9121

Context:
- `ImageTextureLoader` depends on `RenderDevice` to work out which
compressed image formats it can support
- `RenderDevice` is initialised by `RenderPlugin`
- #8336 made `RenderPlugin`
initialisation async
- This caused `RenderDevice` to be missing at the time of
`ImageTextureLoader` initialisation, which in turn meant UASTC encoded
ktx2 textures were being converted to unsupported formats, and thus
caused panics

## Solution

- Delay `ImageTextureLoader` initialisation

---

## Changelog

- Moved `ImageTextureLoader` initialisation from `ImagePlugin::build()`
to `ImagePlugin::finish()`
- Default to `CompressedImageFormats::NONE` if `RenderDevice` resource
is missing

---------

Co-authored-by: 66OJ66 <hi0obxud@anonaddy.me>
cart pushed a commit that referenced this issue Aug 10, 2023
# Objective

Fixes #9121

Context:
- `ImageTextureLoader` depends on `RenderDevice` to work out which
compressed image formats it can support
- `RenderDevice` is initialised by `RenderPlugin`
- #8336 made `RenderPlugin`
initialisation async
- This caused `RenderDevice` to be missing at the time of
`ImageTextureLoader` initialisation, which in turn meant UASTC encoded
ktx2 textures were being converted to unsupported formats, and thus
caused panics

## Solution

- Delay `ImageTextureLoader` initialisation

---

## Changelog

- Moved `ImageTextureLoader` initialisation from `ImagePlugin::build()`
to `ImagePlugin::finish()`
- Default to `CompressedImageFormats::NONE` if `RenderDevice` resource
is missing

---------

Co-authored-by: 66OJ66 <hi0obxud@anonaddy.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants