From 831fe305e472113228fe5d9b74d260b4edc70427 Mon Sep 17 00:00:00 2001 From: Rob Parrett Date: Mon, 5 May 2025 09:42:36 -0700 Subject: [PATCH] Update ktx2 to 0.4.0 (#19073) # Objective Adopted #19065 Closes #19065 Updates the requirements on [ktx2](https://github.com/BVE-Reborn/ktx2) to permit the latest version. - [Release notes](https://github.com/BVE-Reborn/ktx2/releases) - [Changelog](https://github.com/BVE-Reborn/ktx2/blob/trunk/CHANGELOG.md) - [Commits](https://github.com/BVE-Reborn/ktx2/compare/v0.3.0...v0.4.0) # Overview - Some renames - A `u8` became `NonZero` - Some methods return a new `Level` struct with a `data` member instead of raw level data. # Testing - Passed CI locally - Ran several examples which utilize `ktx2` files: `scrolling_fog`, `mixed_lighting`, `skybox`, `lightmaps`. --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- crates/bevy_image/Cargo.toml | 2 +- crates/bevy_image/src/ktx2.rs | 73 +++++++++++++++++------------------ crates/bevy_render/Cargo.toml | 2 +- 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/crates/bevy_image/Cargo.toml b/crates/bevy_image/Cargo.toml index a90a3abb80..988325c707 100644 --- a/crates/bevy_image/Cargo.toml +++ b/crates/bevy_image/Cargo.toml @@ -66,7 +66,7 @@ futures-lite = "2.0.1" guillotiere = "0.6.0" rectangle-pack = "0.4" ddsfile = { version = "0.5.2", optional = true } -ktx2 = { version = "0.3.0", optional = true } +ktx2 = { version = "0.4.0", optional = true } # For ktx2 supercompression flate2 = { version = "1.0.22", optional = true } ruzstd = { version = "0.8.0", optional = true } diff --git a/crates/bevy_image/src/ktx2.rs b/crates/bevy_image/src/ktx2.rs index bffea83d10..0cccbacb07 100644 --- a/crates/bevy_image/src/ktx2.rs +++ b/crates/bevy_image/src/ktx2.rs @@ -10,8 +10,8 @@ use bevy_utils::default; #[cfg(any(feature = "flate2", feature = "ruzstd"))] use ktx2::SupercompressionScheme; use ktx2::{ - BasicDataFormatDescriptor, ChannelTypeQualifiers, ColorModel, DataFormatDescriptorHeader, - Header, SampleInformation, + ChannelTypeQualifiers, ColorModel, DfdBlockBasic, DfdBlockHeaderBasic, DfdHeader, Header, + SampleInformation, }; use wgpu_types::{ AstcBlock, AstcChannel, Extent3d, TextureDimension, TextureFormat, TextureViewDescriptor, @@ -45,28 +45,28 @@ pub fn ktx2_buffer_to_image( // Handle supercompression let mut levels = Vec::new(); if let Some(supercompression_scheme) = supercompression_scheme { - for (_level, _level_data) in ktx2.levels().enumerate() { + for (level_index, level) in ktx2.levels().enumerate() { match supercompression_scheme { #[cfg(feature = "flate2")] SupercompressionScheme::ZLIB => { - let mut decoder = flate2::bufread::ZlibDecoder::new(_level_data); + let mut decoder = flate2::bufread::ZlibDecoder::new(level.data); let mut decompressed = Vec::new(); decoder.read_to_end(&mut decompressed).map_err(|err| { TextureError::SuperDecompressionError(format!( - "Failed to decompress {supercompression_scheme:?} for mip {_level}: {err:?}", + "Failed to decompress {supercompression_scheme:?} for mip {level_index}: {err:?}", )) })?; levels.push(decompressed); } #[cfg(feature = "ruzstd")] SupercompressionScheme::Zstandard => { - let mut cursor = std::io::Cursor::new(_level_data); + let mut cursor = std::io::Cursor::new(level.data); let mut decoder = ruzstd::decoding::StreamingDecoder::new(&mut cursor) .map_err(|err| TextureError::SuperDecompressionError(err.to_string()))?; let mut decompressed = Vec::new(); decoder.read_to_end(&mut decompressed).map_err(|err| { TextureError::SuperDecompressionError(format!( - "Failed to decompress {supercompression_scheme:?} for mip {_level}: {err:?}", + "Failed to decompress {supercompression_scheme:?} for mip {level_index}: {err:?}", )) })?; levels.push(decompressed); @@ -79,7 +79,7 @@ pub fn ktx2_buffer_to_image( } } } else { - levels = ktx2.levels().map(<[u8]>::to_vec).collect(); + levels = ktx2.levels().map(|level| level.data.to_vec()).collect(); } // Identify the format @@ -397,16 +397,15 @@ pub fn ktx2_get_texture_format>( return ktx2_format_to_texture_format(format, is_srgb); } - for data_format_descriptor in ktx2.data_format_descriptors() { - if data_format_descriptor.header == DataFormatDescriptorHeader::BASIC { - let basic_data_format_descriptor = - BasicDataFormatDescriptor::parse(data_format_descriptor.data) - .map_err(|err| TextureError::InvalidData(format!("KTX2: {err:?}")))?; + for data_format_descriptor in ktx2.dfd_blocks() { + if data_format_descriptor.header == DfdHeader::BASIC { + let basic_data_format_descriptor = DfdBlockBasic::parse(data_format_descriptor.data) + .map_err(|err| TextureError::InvalidData(format!("KTX2: {err:?}")))?; let sample_information = basic_data_format_descriptor .sample_information() .collect::>(); - return ktx2_dfd_to_texture_format( - &basic_data_format_descriptor, + return ktx2_dfd_header_to_texture_format( + &basic_data_format_descriptor.header, &sample_information, is_srgb, ); @@ -476,8 +475,8 @@ fn sample_information_to_data_type( } #[cfg(feature = "ktx2")] -pub fn ktx2_dfd_to_texture_format( - data_format_descriptor: &BasicDataFormatDescriptor, +pub fn ktx2_dfd_header_to_texture_format( + data_format_descriptor: &DfdBlockHeaderBasic, sample_information: &[SampleInformation], is_srgb: bool, ) -> Result { @@ -495,7 +494,7 @@ pub fn ktx2_dfd_to_texture_format( let sample = &sample_information[0]; let data_type = sample_information_to_data_type(sample, false)?; - match sample.bit_length { + match sample.bit_length.get() { 8 => match data_type { DataType::Unorm => TextureFormat::R8Unorm, DataType::UnormSrgb => { @@ -577,7 +576,7 @@ pub fn ktx2_dfd_to_texture_format( let sample = &sample_information[0]; let data_type = sample_information_to_data_type(sample, false)?; - match sample.bit_length { + match sample.bit_length.get() { 8 => match data_type { DataType::Unorm => TextureFormat::Rg8Unorm, DataType::UnormSrgb => { @@ -635,27 +634,27 @@ pub fn ktx2_dfd_to_texture_format( } 3 => { if sample_information[0].channel_type == 0 - && sample_information[0].bit_length == 11 + && sample_information[0].bit_length.get() == 11 && sample_information[1].channel_type == 1 - && sample_information[1].bit_length == 11 + && sample_information[1].bit_length.get() == 11 && sample_information[2].channel_type == 2 - && sample_information[2].bit_length == 10 + && sample_information[2].bit_length.get() == 10 { TextureFormat::Rg11b10Ufloat } else if sample_information[0].channel_type == 0 - && sample_information[0].bit_length == 9 + && sample_information[0].bit_length.get() == 9 && sample_information[1].channel_type == 1 - && sample_information[1].bit_length == 9 + && sample_information[1].bit_length.get() == 9 && sample_information[2].channel_type == 2 - && sample_information[2].bit_length == 9 + && sample_information[2].bit_length.get() == 9 { TextureFormat::Rgb9e5Ufloat } else if sample_information[0].channel_type == 0 - && sample_information[0].bit_length == 8 + && sample_information[0].bit_length.get() == 8 && sample_information[1].channel_type == 1 - && sample_information[1].bit_length == 8 + && sample_information[1].bit_length.get() == 8 && sample_information[2].channel_type == 2 - && sample_information[2].bit_length == 8 + && sample_information[2].bit_length.get() == 8 { return Err(TextureError::FormatRequiresTranscodingError( TranscodeFormat::Rgb8, @@ -681,10 +680,10 @@ pub fn ktx2_dfd_to_texture_format( assert_eq!(sample_information[3].channel_type, 15); // Handle one special packed format - if sample_information[0].bit_length == 10 - && sample_information[1].bit_length == 10 - && sample_information[2].bit_length == 10 - && sample_information[3].bit_length == 2 + if sample_information[0].bit_length.get() == 10 + && sample_information[1].bit_length.get() == 10 + && sample_information[2].bit_length.get() == 10 + && sample_information[3].bit_length.get() == 2 { return Ok(TextureFormat::Rgb10a2Unorm); } @@ -708,7 +707,7 @@ pub fn ktx2_dfd_to_texture_format( let sample = &sample_information[0]; let data_type = sample_information_to_data_type(sample, is_srgb)?; - match sample.bit_length { + match sample.bit_length.get() { 8 => match data_type { DataType::Unorm => { if is_rgba { @@ -896,7 +895,7 @@ pub fn ktx2_dfd_to_texture_format( Some(ColorModel::XYZW) => { // Same number of channels in both texel block dimensions and sample info descriptions assert_eq!( - data_format_descriptor.texel_block_dimensions[0] as usize, + data_format_descriptor.texel_block_dimensions[0].get() as usize, sample_information.len() ); match sample_information.len() { @@ -935,7 +934,7 @@ pub fn ktx2_dfd_to_texture_format( let sample = &sample_information[0]; let data_type = sample_information_to_data_type(sample, false)?; - match sample.bit_length { + match sample.bit_length.get() { 8 => match data_type { DataType::Unorm => TextureFormat::Rgba8Unorm, DataType::UnormSrgb => { @@ -1124,8 +1123,8 @@ pub fn ktx2_dfd_to_texture_format( }, Some(ColorModel::ASTC) => TextureFormat::Astc { block: match ( - data_format_descriptor.texel_block_dimensions[0], - data_format_descriptor.texel_block_dimensions[1], + data_format_descriptor.texel_block_dimensions[0].get(), + data_format_descriptor.texel_block_dimensions[1].get(), ) { (4, 4) => AstcBlock::B4x4, (5, 4) => AstcBlock::B5x4, diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index 5da61a57dd..aa6b6e239c 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -97,7 +97,7 @@ downcast-rs = { version = "2", default-features = false, features = ["std"] } thiserror = { version = "2", default-features = false } derive_more = { version = "1", default-features = false, features = ["from"] } futures-lite = "2.0.1" -ktx2 = { version = "0.3.0", optional = true } +ktx2 = { version = "0.4.0", optional = true } encase = { version = "0.10", features = ["glam"] } # For wgpu profiling using tracing. Use `RUST_LOG=info` to also capture the wgpu spans. profiling = { version = "1", features = [