Skip to content

Commit

Permalink
bevy_render: Fix KTX2 UASTC format mapping (bevyengine#4569)
Browse files Browse the repository at this point in the history
# 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 bevyengine#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
  • Loading branch information
superdump authored and ItsDoot committed Feb 1, 2023
1 parent 5490a2e commit 226ccf6
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 19 deletions.
10 changes: 5 additions & 5 deletions crates/bevy_render/src/texture/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
28 changes: 14 additions & 14 deletions crates/bevy_render/src/texture/ktx2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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.
Expand Down Expand Up @@ -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,
}),
));
}
Expand Down

0 comments on commit 226ccf6

Please sign in to comment.