Skip to content

Commit

Permalink
bevy_render: Convert KTX2 R8_SRGB/R8G8_SRGB to Unorm for use with wgpu
Browse files Browse the repository at this point in the history
  • Loading branch information
superdump committed Apr 25, 2022
1 parent 88b4b04 commit 99c4382
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 17 deletions.
6 changes: 5 additions & 1 deletion crates/bevy_render/src/texture/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,13 @@ pub enum DataFormat {
#[derive(Clone, Copy, Debug)]
pub enum TranscodeFormat {
Etc1s,
Uastc(DataFormat),
// Has to be transcoded to R8Unorm for use with `wgpu`
R8UnormSrgb,
// Has to be transcoded to R8G8Unorm for use with `wgpu`
Rg8UnormSrgb,
// Has to be transcoded to Rgba8 for use with `wgpu`
Rgb8,
Uastc(DataFormat),
}

/// An error that occurs when loading a texture
Expand Down
67 changes: 51 additions & 16 deletions crates/bevy_render/src/texture/ktx2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cfg(any(feature = "flate2", feature = "ruzstd"))]
use std::io::Read;

use crate::color::SrgbColorSpace;
#[cfg(feature = "basis-universal")]
use basis_universal::{
DecodeFlags, LowLevelUastcTranscoder, SliceParametersUastc, TranscoderBlockFormat,
Expand Down Expand Up @@ -82,6 +83,44 @@ pub fn ktx2_buffer_to_image(
TextureError::FormatRequiresTranscodingError(transcode_format) => {
let mut transcoded = Vec::new();
let texture_format = match transcode_format {
TranscodeFormat::R8UnormSrgb => {
let (mut original_width, mut original_height) = (width, height);

for level_data in levels.iter() {
transcoded.push(
level_data
.iter()
.copied()
.map(|v| v.nonlinear_to_linear_srgb())
.collect::<Vec<u8>>(),
);

// Next mip dimensions are half the current, minimum 1x1
original_width = (original_width / 2).max(1);
original_height = (original_height / 2).max(1);
}

TextureFormat::R8Unorm
}
TranscodeFormat::Rg8UnormSrgb => {
let (mut original_width, mut original_height) = (width, height);

for level_data in levels.iter() {
transcoded.push(
level_data
.iter()
.copied()
.map(|v| v.nonlinear_to_linear_srgb())
.collect::<Vec<u8>>(),
);

// Next mip dimensions are half the current, minimum 1x1
original_width = (original_width / 2).max(1);
original_height = (original_height / 2).max(1);
}

TextureFormat::Rg8Unorm
}
TranscodeFormat::Rgb8 => {
let (mut original_width, mut original_height) = (width, height);

Expand Down Expand Up @@ -1283,10 +1322,9 @@ pub fn ktx2_format_to_texture_format(
Ok(match ktx2_format {
ktx2::Format::R8_UNORM => {
if is_srgb {
return Err(TextureError::UnsupportedTextureFormat(format!(
"{:?}",
ktx2_format
)));
return Err(TextureError::FormatRequiresTranscodingError(
TranscodeFormat::R8UnormSrgb,
));
} else {
TextureFormat::R8Unorm
}
Expand All @@ -1296,20 +1334,18 @@ pub fn ktx2_format_to_texture_format(
ktx2::Format::R8_SINT => TextureFormat::R8Sint,
ktx2::Format::R8_SRGB => {
if is_srgb {
return Err(TextureError::UnsupportedTextureFormat(format!(
"{:?}",
ktx2_format
)));
return Err(TextureError::FormatRequiresTranscodingError(
TranscodeFormat::R8UnormSrgb,
));
} else {
TextureFormat::R8Unorm
}
}
ktx2::Format::R8G8_UNORM => {
if is_srgb {
return Err(TextureError::UnsupportedTextureFormat(format!(
"{:?}",
ktx2_format
)));
return Err(TextureError::FormatRequiresTranscodingError(
TranscodeFormat::Rg8UnormSrgb,
));
} else {
TextureFormat::Rg8Unorm
}
Expand All @@ -1319,10 +1355,9 @@ pub fn ktx2_format_to_texture_format(
ktx2::Format::R8G8_SINT => TextureFormat::Rg8Sint,
ktx2::Format::R8G8_SRGB => {
if is_srgb {
return Err(TextureError::UnsupportedTextureFormat(format!(
"{:?}",
ktx2_format
)));
return Err(TextureError::FormatRequiresTranscodingError(
TranscodeFormat::Rg8UnormSrgb,
));
} else {
TextureFormat::Rg8Unorm
}
Expand Down

0 comments on commit 99c4382

Please sign in to comment.