From caa61c5fb7990a816766d0797a81a8a9ac07b3e8 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Fri, 17 Jun 2022 00:14:02 +0000 Subject: [PATCH] bevy_render: Fix KTX2 UASTC format mapping (#4569) # Objective - KTX2 UASTC format mapping was incorrect. For some reason I had written it to map to a set of data formats based on the count of KTX2 sample information blocks, but the mapping should be done based on the channel type in the sample information. - This is a valid change pulled out from #4514 as the attempt to fix the array textures there was incorrect ## Solution - Fix the KTX2 UASTC `DataFormat` enum to contain the correct formats based on the channel types in section 3.10.2 of https://github.khronos.org/KTX-Specification/ (search for "Basis Universal UASTC Format") - Correctly map from the sample information channel type to `DataFormat` - Correctly configure transcoding and the resulting texture format based on the `DataFormat` --- ## Changelog - Fixed: KTX2 UASTC format handling --- crates/bevy_render/src/texture/image.rs | 10 ++++----- crates/bevy_render/src/texture/ktx2.rs | 28 ++++++++++++------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index f898140acbd73..bec554b1f6b57 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -373,11 +373,11 @@ impl Image { #[derive(Clone, Copy, Debug)] pub enum DataFormat { - R8, - Rg8, - Rgb8, - Rgba8, - Rgba16Float, + Rgb, + Rgba, + Rrr, + Rrrg, + Rg, } #[derive(Clone, Copy, Debug)] diff --git a/crates/bevy_render/src/texture/ktx2.rs b/crates/bevy_render/src/texture/ktx2.rs index 94830d7ac4aa0..7a4fb62682ba2 100644 --- a/crates/bevy_render/src/texture/ktx2.rs +++ b/crates/bevy_render/src/texture/ktx2.rs @@ -206,7 +206,7 @@ pub fn get_transcoded_formats( is_srgb: bool, ) -> (TranscoderBlockFormat, TextureFormat) { match data_format { - DataFormat::R8 => { + DataFormat::Rrr => { if supported_compressed_formats.contains(CompressedImageFormats::BC) { (TranscoderBlockFormat::BC4, TextureFormat::Bc4RUnorm) } else if supported_compressed_formats.contains(CompressedImageFormats::ETC2) { @@ -218,7 +218,7 @@ pub fn get_transcoded_formats( (TranscoderBlockFormat::RGBA32, TextureFormat::R8Unorm) } } - DataFormat::Rg8 => { + DataFormat::Rrrg | DataFormat::Rg => { if supported_compressed_formats.contains(CompressedImageFormats::BC) { (TranscoderBlockFormat::BC5, TextureFormat::Bc5RgUnorm) } else if supported_compressed_formats.contains(CompressedImageFormats::ETC2) { @@ -232,7 +232,7 @@ pub fn get_transcoded_formats( } // NOTE: Rgba16Float should be transcoded to BC6H/ASTC_HDR. Neither are supported by // basis-universal, nor is ASTC_HDR supported by wgpu - DataFormat::Rgb8 | DataFormat::Rgba8 | DataFormat::Rgba16Float => { + DataFormat::Rgb | DataFormat::Rgba => { // NOTE: UASTC can be losslessly transcoded to ASTC4x4 and ASTC uses the same // space as BC7 (128-bits per 4x4 texel block) so prefer ASTC over BC for // transcoding speed and quality. @@ -1187,18 +1187,18 @@ pub fn ktx2_dfd_to_texture_format( } Some(ColorModel::UASTC) => { return Err(TextureError::FormatRequiresTranscodingError( - TranscodeFormat::Uastc(match sample_information.len() { - 1 => DataFormat::R8, - 2 => DataFormat::Rg8, - 3 => DataFormat::Rgb8, - 4 => { - if sample_information[0].bit_length == 8 { - DataFormat::Rgba8 - } else { - DataFormat::Rgba16Float - } + TranscodeFormat::Uastc(match sample_information[0].channel_type { + 0 => DataFormat::Rgb, + 3 => DataFormat::Rgba, + 4 => DataFormat::Rrr, + 5 => DataFormat::Rrrg, + 6 => DataFormat::Rg, + channel_type => { + return Err(TextureError::UnsupportedTextureFormat(format!( + "Invalid KTX2 UASTC channel type: {}", + channel_type + ))) } - _ => DataFormat::Rgba8, }), )); }