2022-03-15 22:26:46 +00:00
|
|
|
#[cfg(any(feature = "flate2", feature = "ruzstd"))]
|
|
|
|
use std::io::Read;
|
|
|
|
|
|
|
|
#[cfg(feature = "basis-universal")]
|
|
|
|
use basis_universal::{
|
|
|
|
DecodeFlags, LowLevelUastcTranscoder, SliceParametersUastc, TranscoderBlockFormat,
|
|
|
|
};
|
2024-02-25 22:35:00 +00:00
|
|
|
use bevy_color::Srgba;
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
use bevy_utils::default;
|
2022-03-15 22:26:46 +00:00
|
|
|
#[cfg(any(feature = "flate2", feature = "ruzstd"))]
|
|
|
|
use ktx2::SupercompressionScheme;
|
|
|
|
use ktx2::{
|
|
|
|
BasicDataFormatDescriptor, ChannelTypeQualifiers, ColorModel, DataFormatDescriptorHeader,
|
|
|
|
Header, SampleInformation,
|
|
|
|
};
|
2024-12-03 11:46:10 +00:00
|
|
|
use wgpu::TextureViewDescriptor;
|
|
|
|
use wgpu_types::{
|
|
|
|
AstcBlock, AstcChannel, Extent3d, TextureDimension, TextureFormat, TextureViewDimension,
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
};
|
2022-03-15 22:26:46 +00:00
|
|
|
|
|
|
|
use super::{CompressedImageFormats, DataFormat, Image, TextureError, TranscodeFormat};
|
|
|
|
|
Add feature requirement info to image loading docs (#13712)
# Objective
- Add "Available on crate feature <image format> only." for docs of
image format related types/functions
- Add warning "WARN bevy_render::texture::image: feature "<image
format>" is not enabled" on load attempt
- Fixes #13468 .
## Solution
- Added #[cfg(feature = "<image format>")] for types and warn!("feature
\"<image format>\" is not enabled"); for ImageFormat enum conversions
## Testing
ran reproducing example from issue #13468 and saw in logs
`WARN bevy_render::texture::image: feature "exr" is not enabled`
generated docs with command `RUSTDOCFLAGS="-Zunstable-options
--cfg=docsrs" cargo +nightly doc --workspace --all-features --no-deps
--document-private-items --open` and saw
![image](https://github.com/bevyengine/bevy/assets/17225606/820262bb-b4e6-4a5e-a306-bddbe9c40852)
that docs contain `Available on crate feature <image format> only.`
marks
![image](https://github.com/bevyengine/bevy/assets/17225606/57463440-a2ea-435f-a2c2-50d34f7f55a9)
## Migration Guide
Image format related entities are feature gated, if there are
compilation errors about unknown names there are some of features in
list (`exr`, `hdr`, `basis-universal`, `png`, `dds`, `tga`, `jpeg`,
`bmp`, `ktx2`, `webp` and `pnm`) should be added.
2024-08-16 23:43:20 +00:00
|
|
|
#[cfg(feature = "ktx2")]
|
2022-03-15 22:26:46 +00:00
|
|
|
pub fn ktx2_buffer_to_image(
|
|
|
|
buffer: &[u8],
|
|
|
|
supported_compressed_formats: CompressedImageFormats,
|
|
|
|
is_srgb: bool,
|
|
|
|
) -> Result<Image, TextureError> {
|
2022-10-28 21:03:01 +00:00
|
|
|
let ktx2 = ktx2::Reader::new(buffer)
|
|
|
|
.map_err(|err| TextureError::InvalidData(format!("Failed to parse ktx2 file: {err:?}")))?;
|
2022-03-15 22:26:46 +00:00
|
|
|
let Header {
|
|
|
|
pixel_width: width,
|
|
|
|
pixel_height: height,
|
|
|
|
pixel_depth: depth,
|
|
|
|
layer_count,
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
face_count,
|
2022-03-15 22:26:46 +00:00
|
|
|
level_count,
|
|
|
|
supercompression_scheme,
|
|
|
|
..
|
|
|
|
} = ktx2.header();
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
let layer_count = layer_count.max(1);
|
|
|
|
let face_count = face_count.max(1);
|
|
|
|
let depth = depth.max(1);
|
2022-03-15 22:26:46 +00:00
|
|
|
|
|
|
|
// Handle supercompression
|
|
|
|
let mut levels = Vec::new();
|
|
|
|
if let Some(supercompression_scheme) = supercompression_scheme {
|
|
|
|
for (_level, _level_data) in ktx2.levels().enumerate() {
|
|
|
|
match supercompression_scheme {
|
|
|
|
#[cfg(feature = "flate2")]
|
|
|
|
SupercompressionScheme::ZLIB => {
|
|
|
|
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!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Failed to decompress {supercompression_scheme:?} for mip {_level}: {err:?}",
|
2022-03-15 22:26:46 +00:00
|
|
|
))
|
|
|
|
})?;
|
|
|
|
levels.push(decompressed);
|
|
|
|
}
|
|
|
|
#[cfg(feature = "ruzstd")]
|
|
|
|
SupercompressionScheme::Zstandard => {
|
|
|
|
let mut cursor = std::io::Cursor::new(_level_data);
|
|
|
|
let mut decoder = ruzstd::StreamingDecoder::new(&mut cursor)
|
2023-05-17 23:29:31 +00:00
|
|
|
.map_err(|err| TextureError::SuperDecompressionError(err.to_string()))?;
|
2022-03-15 22:26:46 +00:00
|
|
|
let mut decompressed = Vec::new();
|
|
|
|
decoder.read_to_end(&mut decompressed).map_err(|err| {
|
|
|
|
TextureError::SuperDecompressionError(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Failed to decompress {supercompression_scheme:?} for mip {_level}: {err:?}",
|
2022-03-15 22:26:46 +00:00
|
|
|
))
|
|
|
|
})?;
|
|
|
|
levels.push(decompressed);
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
return Err(TextureError::SuperDecompressionError(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Unsupported supercompression scheme: {supercompression_scheme:?}",
|
2022-03-15 22:26:46 +00:00
|
|
|
)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2024-07-01 15:54:40 +00:00
|
|
|
levels = ktx2.levels().map(<[u8]>::to_vec).collect();
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Identify the format
|
|
|
|
let texture_format = ktx2_get_texture_format(&ktx2, is_srgb).or_else(|error| match error {
|
|
|
|
// Transcode if needed and supported
|
|
|
|
TextureError::FormatRequiresTranscodingError(transcode_format) => {
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
let mut transcoded = vec![Vec::default(); levels.len()];
|
2022-03-15 22:26:46 +00:00
|
|
|
let texture_format = match transcode_format {
|
Fix KTX2 R8_SRGB, R8_UNORM, R8G8_SRGB, R8G8_UNORM, R8G8B8_SRGB, R8G8B8_UNORM support (#4594)
# Objective
- Fixes #4592
## Solution
- Implement `SrgbColorSpace` for `u8` via `f32`
- Convert KTX2 R8 and R8G8 non-linear sRGB to wgpu `R8Unorm` and `Rg8Unorm` as non-linear sRGB are not supported by wgpu for these formats
- Convert KTX2 R8G8B8 formats to `Rgba8Unorm` and `Rgba8UnormSrgb` by adding an alpha channel as the Rgb variants don't exist in wgpu
---
## Changelog
- Added: Support for KTX2 `R8_SRGB`, `R8_UNORM`, `R8G8_SRGB`, `R8G8_UNORM`, `R8G8B8_SRGB`, `R8G8B8_UNORM` formats by converting to supported wgpu formats as appropriate
2023-01-30 09:04:08 +00:00
|
|
|
TranscodeFormat::R8UnormSrgb => {
|
|
|
|
let (mut original_width, mut original_height) = (width, height);
|
|
|
|
|
2024-04-14 14:40:10 +00:00
|
|
|
for (level, level_data) in levels.iter().enumerate() {
|
|
|
|
transcoded[level] = level_data
|
|
|
|
.iter()
|
|
|
|
.copied()
|
|
|
|
.map(|v| (Srgba::gamma_function(v as f32 / 255.) * 255.).floor() as u8)
|
|
|
|
.collect::<Vec<u8>>();
|
Fix KTX2 R8_SRGB, R8_UNORM, R8G8_SRGB, R8G8_UNORM, R8G8B8_SRGB, R8G8B8_UNORM support (#4594)
# Objective
- Fixes #4592
## Solution
- Implement `SrgbColorSpace` for `u8` via `f32`
- Convert KTX2 R8 and R8G8 non-linear sRGB to wgpu `R8Unorm` and `Rg8Unorm` as non-linear sRGB are not supported by wgpu for these formats
- Convert KTX2 R8G8B8 formats to `Rgba8Unorm` and `Rgba8UnormSrgb` by adding an alpha channel as the Rgb variants don't exist in wgpu
---
## Changelog
- Added: Support for KTX2 `R8_SRGB`, `R8_UNORM`, `R8G8_SRGB`, `R8G8_UNORM`, `R8G8B8_SRGB`, `R8G8B8_UNORM` formats by converting to supported wgpu formats as appropriate
2023-01-30 09:04:08 +00:00
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
2024-04-14 14:40:10 +00:00
|
|
|
for (level, level_data) in levels.iter().enumerate() {
|
|
|
|
transcoded[level] = level_data
|
|
|
|
.iter()
|
|
|
|
.copied()
|
|
|
|
.map(|v| (Srgba::gamma_function(v as f32 / 255.) * 255.).floor() as u8)
|
|
|
|
.collect::<Vec<u8>>();
|
Fix KTX2 R8_SRGB, R8_UNORM, R8G8_SRGB, R8G8_UNORM, R8G8B8_SRGB, R8G8B8_UNORM support (#4594)
# Objective
- Fixes #4592
## Solution
- Implement `SrgbColorSpace` for `u8` via `f32`
- Convert KTX2 R8 and R8G8 non-linear sRGB to wgpu `R8Unorm` and `Rg8Unorm` as non-linear sRGB are not supported by wgpu for these formats
- Convert KTX2 R8G8B8 formats to `Rgba8Unorm` and `Rgba8UnormSrgb` by adding an alpha channel as the Rgb variants don't exist in wgpu
---
## Changelog
- Added: Support for KTX2 `R8_SRGB`, `R8_UNORM`, `R8G8_SRGB`, `R8G8_UNORM`, `R8G8B8_SRGB`, `R8G8B8_UNORM` formats by converting to supported wgpu formats as appropriate
2023-01-30 09:04:08 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
2022-03-15 22:26:46 +00:00
|
|
|
TranscodeFormat::Rgb8 => {
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
let mut rgba = vec![255u8; width as usize * height as usize * 4];
|
|
|
|
for (level, level_data) in levels.iter().enumerate() {
|
|
|
|
let n_pixels = (width as usize >> level).max(1) * (height as usize >> level).max(1);
|
2022-03-15 22:26:46 +00:00
|
|
|
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
let mut offset = 0;
|
|
|
|
for _layer in 0..layer_count {
|
|
|
|
for _face in 0..face_count {
|
|
|
|
for i in 0..n_pixels {
|
|
|
|
rgba[i * 4] = level_data[offset];
|
|
|
|
rgba[i * 4 + 1] = level_data[offset + 1];
|
|
|
|
rgba[i * 4 + 2] = level_data[offset + 2];
|
|
|
|
offset += 3;
|
|
|
|
}
|
2023-08-24 00:35:52 +00:00
|
|
|
transcoded[level].extend_from_slice(&rgba[0..n_pixels * 4]);
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
}
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Rgba8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Rgba8Unorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#[cfg(feature = "basis-universal")]
|
|
|
|
TranscodeFormat::Uastc(data_format) => {
|
|
|
|
let (transcode_block_format, texture_format) =
|
|
|
|
get_transcoded_formats(supported_compressed_formats, data_format, is_srgb);
|
2023-04-26 15:34:23 +00:00
|
|
|
let texture_format_info = texture_format;
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
let (block_width_pixels, block_height_pixels) = (
|
2023-04-26 15:34:23 +00:00
|
|
|
texture_format_info.block_dimensions().0,
|
|
|
|
texture_format_info.block_dimensions().1,
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
);
|
2023-04-26 15:34:23 +00:00
|
|
|
// Texture is not a depth or stencil format, it is possible to pass `None` and unwrap
|
Update to wgpu 0.19 and raw-window-handle 0.6 (#11280)
# Objective
Keep core dependencies up to date.
## Solution
Update the dependencies.
wgpu 0.19 only supports raw-window-handle (rwh) 0.6, so bumping that was
included in this.
The rwh 0.6 version bump is just the simplest way of doing it. There
might be a way we can take advantage of wgpu's new safe surface creation
api, but I'm not familiar enough with bevy's window management to
untangle it and my attempt ended up being a mess of lifetimes and rustc
complaining about missing trait impls (that were implemented). Thanks to
@MiniaczQ for the (much simpler) rwh 0.6 version bump code.
Unblocks https://github.com/bevyengine/bevy/pull/9172 and
https://github.com/bevyengine/bevy/pull/10812
~~This might be blocked on cpal and oboe updating their ndk versions to
0.8, as they both currently target ndk 0.7 which uses rwh 0.5.2~~ Tested
on android, and everything seems to work correctly (audio properly stops
when minimized, and plays when re-focusing the app).
---
## Changelog
- `wgpu` has been updated to 0.19! The long awaited arcanization has
been merged (for more info, see
https://gfx-rs.github.io/2023/11/24/arcanization.html), and Vulkan
should now be working again on Intel GPUs.
- Targeting WebGPU now requires that you add the new `webgpu` feature
(setting the `RUSTFLAGS` environment variable to
`--cfg=web_sys_unstable_apis` is still required). This feature currently
overrides the `webgl2` feature if you have both enabled (the `webgl2`
feature is enabled by default), so it is not recommended to add it as a
default feature to libraries without putting it behind a flag that
allows library users to opt out of it! In the future we plan on
supporting wasm binaries that can target both webgl2 and webgpu now that
wgpu added support for doing so (see
https://github.com/bevyengine/bevy/issues/11505).
- `raw-window-handle` has been updated to version 0.6.
## Migration Guide
- `bevy_render::instance_index::get_instance_index()` has been removed
as the webgl2 workaround is no longer required as it was fixed upstream
in wgpu. The `BASE_INSTANCE_WORKAROUND` shaderdef has also been removed.
- WebGPU now requires the new `webgpu` feature to be enabled. The
`webgpu` feature currently overrides the `webgl2` feature so you no
longer need to disable all default features and re-add them all when
targeting `webgpu`, but binaries built with both the `webgpu` and
`webgl2` features will only target the webgpu backend, and will only
work on browsers that support WebGPU.
- Places where you conditionally compiled things for webgl2 need to be
updated because of this change, eg:
- `#[cfg(any(not(feature = "webgl"), not(target_arch = "wasm32")))]`
becomes `#[cfg(any(not(feature = "webgl") ,not(target_arch = "wasm32"),
feature = "webgpu"))]`
- `#[cfg(all(feature = "webgl", target_arch = "wasm32"))]` becomes
`#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature =
"webgpu")))]`
- `if cfg!(all(feature = "webgl", target_arch = "wasm32"))` becomes `if
cfg!(all(feature = "webgl", target_arch = "wasm32", not(feature =
"webgpu")))`
- `create_texture_with_data` now also takes a `TextureDataOrder`. You
can probably just set this to `TextureDataOrder::default()`
- `TextureFormat`'s `block_size` has been renamed to `block_copy_size`
- See the `wgpu` changelog for anything I might've missed:
https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md
---------
Co-authored-by: François <mockersf@gmail.com>
2024-01-26 18:14:21 +00:00
|
|
|
let block_bytes = texture_format_info.block_copy_size(None).unwrap();
|
2022-03-15 22:26:46 +00:00
|
|
|
|
|
|
|
let transcoder = LowLevelUastcTranscoder::new();
|
|
|
|
for (level, level_data) in levels.iter().enumerate() {
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
let (level_width, level_height) = (
|
|
|
|
(width >> level as u32).max(1),
|
|
|
|
(height >> level as u32).max(1),
|
|
|
|
);
|
|
|
|
let (num_blocks_x, num_blocks_y) = (
|
2024-10-14 20:52:35 +00:00
|
|
|
level_width.div_ceil(block_width_pixels) .max(1),
|
|
|
|
level_height.div_ceil(block_height_pixels) .max(1),
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
);
|
|
|
|
let level_bytes = (num_blocks_x * num_blocks_y * block_bytes) as usize;
|
2022-03-15 22:26:46 +00:00
|
|
|
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
let mut offset = 0;
|
|
|
|
for _layer in 0..layer_count {
|
|
|
|
for _face in 0..face_count {
|
|
|
|
// NOTE: SliceParametersUastc does not implement Clone nor Copy so
|
|
|
|
// it has to be created per use
|
|
|
|
let slice_parameters = SliceParametersUastc {
|
|
|
|
num_blocks_x,
|
|
|
|
num_blocks_y,
|
|
|
|
has_alpha: false,
|
|
|
|
original_width: level_width,
|
|
|
|
original_height: level_height,
|
|
|
|
};
|
|
|
|
transcoder
|
|
|
|
.transcode_slice(
|
|
|
|
&level_data[offset..(offset + level_bytes)],
|
|
|
|
slice_parameters,
|
|
|
|
DecodeFlags::HIGH_QUALITY,
|
|
|
|
transcode_block_format,
|
|
|
|
)
|
|
|
|
.map(|mut transcoded_level| transcoded[level].append(&mut transcoded_level))
|
|
|
|
.map_err(|error| {
|
|
|
|
TextureError::SuperDecompressionError(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Failed to transcode mip level {level} from UASTC to {transcode_block_format:?}: {error:?}",
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
))
|
|
|
|
})?;
|
|
|
|
offset += level_bytes;
|
|
|
|
}
|
|
|
|
}
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
texture_format
|
|
|
|
}
|
|
|
|
// ETC1S is a subset of ETC1 which is a subset of ETC2
|
|
|
|
// TODO: Implement transcoding
|
|
|
|
TranscodeFormat::Etc1s => {
|
|
|
|
let texture_format = if is_srgb {
|
|
|
|
TextureFormat::Etc2Rgb8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Etc2Rgb8Unorm
|
|
|
|
};
|
|
|
|
if !supported_compressed_formats.supports(texture_format) {
|
|
|
|
return Err(error);
|
|
|
|
}
|
|
|
|
transcoded = levels.to_vec();
|
|
|
|
texture_format
|
|
|
|
}
|
|
|
|
#[cfg(not(feature = "basis-universal"))]
|
|
|
|
_ => return Err(error),
|
|
|
|
};
|
|
|
|
levels = transcoded;
|
|
|
|
Ok(texture_format)
|
|
|
|
}
|
|
|
|
_ => Err(error),
|
|
|
|
})?;
|
|
|
|
if !supported_compressed_formats.supports(texture_format) {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Format not supported by this GPU: {texture_format:?}",
|
2022-03-15 22:26:46 +00:00
|
|
|
)));
|
|
|
|
}
|
|
|
|
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
// Reorder data from KTX2 MipXLayerYFaceZ to wgpu LayerYFaceZMipX
|
2023-04-26 15:34:23 +00:00
|
|
|
let texture_format_info = texture_format;
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
let (block_width_pixels, block_height_pixels) = (
|
2023-04-26 15:34:23 +00:00
|
|
|
texture_format_info.block_dimensions().0 as usize,
|
|
|
|
texture_format_info.block_dimensions().1 as usize,
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
);
|
2023-04-26 15:34:23 +00:00
|
|
|
// Texture is not a depth or stencil format, it is possible to pass `None` and unwrap
|
Update to wgpu 0.19 and raw-window-handle 0.6 (#11280)
# Objective
Keep core dependencies up to date.
## Solution
Update the dependencies.
wgpu 0.19 only supports raw-window-handle (rwh) 0.6, so bumping that was
included in this.
The rwh 0.6 version bump is just the simplest way of doing it. There
might be a way we can take advantage of wgpu's new safe surface creation
api, but I'm not familiar enough with bevy's window management to
untangle it and my attempt ended up being a mess of lifetimes and rustc
complaining about missing trait impls (that were implemented). Thanks to
@MiniaczQ for the (much simpler) rwh 0.6 version bump code.
Unblocks https://github.com/bevyengine/bevy/pull/9172 and
https://github.com/bevyengine/bevy/pull/10812
~~This might be blocked on cpal and oboe updating their ndk versions to
0.8, as they both currently target ndk 0.7 which uses rwh 0.5.2~~ Tested
on android, and everything seems to work correctly (audio properly stops
when minimized, and plays when re-focusing the app).
---
## Changelog
- `wgpu` has been updated to 0.19! The long awaited arcanization has
been merged (for more info, see
https://gfx-rs.github.io/2023/11/24/arcanization.html), and Vulkan
should now be working again on Intel GPUs.
- Targeting WebGPU now requires that you add the new `webgpu` feature
(setting the `RUSTFLAGS` environment variable to
`--cfg=web_sys_unstable_apis` is still required). This feature currently
overrides the `webgl2` feature if you have both enabled (the `webgl2`
feature is enabled by default), so it is not recommended to add it as a
default feature to libraries without putting it behind a flag that
allows library users to opt out of it! In the future we plan on
supporting wasm binaries that can target both webgl2 and webgpu now that
wgpu added support for doing so (see
https://github.com/bevyengine/bevy/issues/11505).
- `raw-window-handle` has been updated to version 0.6.
## Migration Guide
- `bevy_render::instance_index::get_instance_index()` has been removed
as the webgl2 workaround is no longer required as it was fixed upstream
in wgpu. The `BASE_INSTANCE_WORKAROUND` shaderdef has also been removed.
- WebGPU now requires the new `webgpu` feature to be enabled. The
`webgpu` feature currently overrides the `webgl2` feature so you no
longer need to disable all default features and re-add them all when
targeting `webgpu`, but binaries built with both the `webgpu` and
`webgl2` features will only target the webgpu backend, and will only
work on browsers that support WebGPU.
- Places where you conditionally compiled things for webgl2 need to be
updated because of this change, eg:
- `#[cfg(any(not(feature = "webgl"), not(target_arch = "wasm32")))]`
becomes `#[cfg(any(not(feature = "webgl") ,not(target_arch = "wasm32"),
feature = "webgpu"))]`
- `#[cfg(all(feature = "webgl", target_arch = "wasm32"))]` becomes
`#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature =
"webgpu")))]`
- `if cfg!(all(feature = "webgl", target_arch = "wasm32"))` becomes `if
cfg!(all(feature = "webgl", target_arch = "wasm32", not(feature =
"webgpu")))`
- `create_texture_with_data` now also takes a `TextureDataOrder`. You
can probably just set this to `TextureDataOrder::default()`
- `TextureFormat`'s `block_size` has been renamed to `block_copy_size`
- See the `wgpu` changelog for anything I might've missed:
https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md
---------
Co-authored-by: François <mockersf@gmail.com>
2024-01-26 18:14:21 +00:00
|
|
|
let block_bytes = texture_format_info.block_copy_size(None).unwrap() as usize;
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
|
|
|
|
let mut wgpu_data = vec![Vec::default(); (layer_count * face_count) as usize];
|
|
|
|
for (level, level_data) in levels.iter().enumerate() {
|
2023-02-19 20:38:13 +00:00
|
|
|
let (level_width, level_height, level_depth) = (
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
(width as usize >> level).max(1),
|
|
|
|
(height as usize >> level).max(1),
|
2023-02-19 20:38:13 +00:00
|
|
|
(depth as usize >> level).max(1),
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
);
|
|
|
|
let (num_blocks_x, num_blocks_y) = (
|
2024-10-14 20:52:35 +00:00
|
|
|
level_width.div_ceil(block_width_pixels).max(1),
|
|
|
|
level_height.div_ceil(block_height_pixels).max(1),
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
);
|
2023-02-19 20:38:13 +00:00
|
|
|
let level_bytes = num_blocks_x * num_blocks_y * level_depth * block_bytes;
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
|
|
|
|
let mut index = 0;
|
|
|
|
for _layer in 0..layer_count {
|
|
|
|
for _face in 0..face_count {
|
|
|
|
let offset = index * level_bytes;
|
|
|
|
wgpu_data[index].extend_from_slice(&level_data[offset..(offset + level_bytes)]);
|
|
|
|
index += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-15 22:26:46 +00:00
|
|
|
// Assign the data and fill in the rest of the metadata now the possible
|
|
|
|
// error cases have been handled
|
|
|
|
let mut image = Image::default();
|
|
|
|
image.texture_descriptor.format = texture_format;
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
image.data = wgpu_data.into_iter().flatten().collect::<Vec<_>>();
|
2022-03-15 22:26:46 +00:00
|
|
|
image.texture_descriptor.size = Extent3d {
|
|
|
|
width,
|
|
|
|
height,
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
depth_or_array_layers: if layer_count > 1 || face_count > 1 {
|
|
|
|
layer_count * face_count
|
|
|
|
} else {
|
|
|
|
depth
|
|
|
|
}
|
|
|
|
.max(1),
|
|
|
|
}
|
|
|
|
.physical_size(texture_format);
|
2022-03-15 22:26:46 +00:00
|
|
|
image.texture_descriptor.mip_level_count = level_count;
|
|
|
|
image.texture_descriptor.dimension = if depth > 1 {
|
|
|
|
TextureDimension::D3
|
|
|
|
} else if image.is_compressed() || height > 1 {
|
|
|
|
TextureDimension::D2
|
|
|
|
} else {
|
|
|
|
TextureDimension::D1
|
|
|
|
};
|
Support array / cubemap / cubemap array textures in KTX2 (#5325)
# Objective
- Fix / support KTX2 array / cubemap / cubemap array textures
- Fixes #4495 . Supersedes #4514 .
## Solution
- Add `Option<TextureViewDescriptor>` to `Image` to enable configuration of the `TextureViewDimension` of a texture.
- This allows users to set `D2Array`, `D3`, `Cube`, `CubeArray` or whatever they need
- Automatically configure this when loading KTX2
- Transcode all layers and faces instead of just one
- Use the UASTC block size of 128 bits, and the number of blocks in x/y for a given mip level in order to determine the offset of the layer and face within the KTX2 mip level data
- `wgpu` wants data ordered as layer 0 mip 0..n, layer 1 mip 0..n, etc. See https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_texture_with_data
- Reorder the data KTX2 mip X layer Y face Z to `wgpu` layer Y face Z mip X order
- Add a `skybox` example to demonstrate / test loading cubemaps from PNG and KTX2, including ASTC 4x4, BC7, and ETC2 compression for support everywhere. Note that you need to enable the `ktx2,zstd` features to be able to load the compressed textures.
---
## Changelog
- Fixed: KTX2 array / cubemap / cubemap array textures
- Fixes: Validation failure for compressed textures stored in KTX2 where the width/height are not a multiple of the block dimensions.
- Added: `Image` now has an `Option<TextureViewDescriptor>` field to enable configuration of the texture view. This is useful for configuring the `TextureViewDimension` when it is not just a plain 2D texture and the loader could/did not identify what it should be.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-30 07:02:58 +00:00
|
|
|
let mut dimension = None;
|
|
|
|
if face_count == 6 {
|
|
|
|
dimension = Some(if layer_count > 1 {
|
|
|
|
TextureViewDimension::CubeArray
|
|
|
|
} else {
|
|
|
|
TextureViewDimension::Cube
|
|
|
|
});
|
|
|
|
} else if layer_count > 1 {
|
|
|
|
dimension = Some(TextureViewDimension::D2Array);
|
|
|
|
} else if depth > 1 {
|
|
|
|
dimension = Some(TextureViewDimension::D3);
|
|
|
|
}
|
|
|
|
if dimension.is_some() {
|
|
|
|
image.texture_view_descriptor = Some(TextureViewDescriptor {
|
|
|
|
dimension,
|
|
|
|
..default()
|
|
|
|
});
|
|
|
|
}
|
2022-03-15 22:26:46 +00:00
|
|
|
Ok(image)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "basis-universal")]
|
|
|
|
pub fn get_transcoded_formats(
|
|
|
|
supported_compressed_formats: CompressedImageFormats,
|
|
|
|
data_format: DataFormat,
|
|
|
|
is_srgb: bool,
|
|
|
|
) -> (TranscoderBlockFormat, TextureFormat) {
|
|
|
|
match data_format {
|
2022-06-17 00:14:02 +00:00
|
|
|
DataFormat::Rrr => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if supported_compressed_formats.contains(CompressedImageFormats::BC) {
|
|
|
|
(TranscoderBlockFormat::BC4, TextureFormat::Bc4RUnorm)
|
|
|
|
} else if supported_compressed_formats.contains(CompressedImageFormats::ETC2) {
|
|
|
|
(
|
|
|
|
TranscoderBlockFormat::ETC2_EAC_R11,
|
|
|
|
TextureFormat::EacR11Unorm,
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
(TranscoderBlockFormat::RGBA32, TextureFormat::R8Unorm)
|
|
|
|
}
|
|
|
|
}
|
2022-06-17 00:14:02 +00:00
|
|
|
DataFormat::Rrrg | DataFormat::Rg => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if supported_compressed_formats.contains(CompressedImageFormats::BC) {
|
|
|
|
(TranscoderBlockFormat::BC5, TextureFormat::Bc5RgUnorm)
|
|
|
|
} else if supported_compressed_formats.contains(CompressedImageFormats::ETC2) {
|
|
|
|
(
|
|
|
|
TranscoderBlockFormat::ETC2_EAC_RG11,
|
|
|
|
TextureFormat::EacRg11Unorm,
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
(TranscoderBlockFormat::RGBA32, TextureFormat::Rg8Unorm)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// NOTE: Rgba16Float should be transcoded to BC6H/ASTC_HDR. Neither are supported by
|
|
|
|
// basis-universal, nor is ASTC_HDR supported by wgpu
|
2022-06-17 00:14:02 +00:00
|
|
|
DataFormat::Rgb | DataFormat::Rgba => {
|
2022-03-15 22:26:46 +00:00
|
|
|
// 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.
|
|
|
|
if supported_compressed_formats.contains(CompressedImageFormats::ASTC_LDR) {
|
|
|
|
(
|
|
|
|
TranscoderBlockFormat::ASTC_4x4,
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B4x4,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
} else if supported_compressed_formats.contains(CompressedImageFormats::BC) {
|
|
|
|
(
|
|
|
|
TranscoderBlockFormat::BC7,
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bc7RgbaUnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc7RgbaUnorm
|
|
|
|
},
|
|
|
|
)
|
|
|
|
} else if supported_compressed_formats.contains(CompressedImageFormats::ETC2) {
|
|
|
|
(
|
|
|
|
TranscoderBlockFormat::ETC2_RGBA,
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Etc2Rgba8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Etc2Rgba8Unorm
|
|
|
|
},
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
(
|
|
|
|
TranscoderBlockFormat::RGBA32,
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Rgba8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Rgba8Unorm
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add feature requirement info to image loading docs (#13712)
# Objective
- Add "Available on crate feature <image format> only." for docs of
image format related types/functions
- Add warning "WARN bevy_render::texture::image: feature "<image
format>" is not enabled" on load attempt
- Fixes #13468 .
## Solution
- Added #[cfg(feature = "<image format>")] for types and warn!("feature
\"<image format>\" is not enabled"); for ImageFormat enum conversions
## Testing
ran reproducing example from issue #13468 and saw in logs
`WARN bevy_render::texture::image: feature "exr" is not enabled`
generated docs with command `RUSTDOCFLAGS="-Zunstable-options
--cfg=docsrs" cargo +nightly doc --workspace --all-features --no-deps
--document-private-items --open` and saw
![image](https://github.com/bevyengine/bevy/assets/17225606/820262bb-b4e6-4a5e-a306-bddbe9c40852)
that docs contain `Available on crate feature <image format> only.`
marks
![image](https://github.com/bevyengine/bevy/assets/17225606/57463440-a2ea-435f-a2c2-50d34f7f55a9)
## Migration Guide
Image format related entities are feature gated, if there are
compilation errors about unknown names there are some of features in
list (`exr`, `hdr`, `basis-universal`, `png`, `dds`, `tga`, `jpeg`,
`bmp`, `ktx2`, `webp` and `pnm`) should be added.
2024-08-16 23:43:20 +00:00
|
|
|
#[cfg(feature = "ktx2")]
|
2022-03-15 22:26:46 +00:00
|
|
|
pub fn ktx2_get_texture_format<Data: AsRef<[u8]>>(
|
|
|
|
ktx2: &ktx2::Reader<Data>,
|
|
|
|
is_srgb: bool,
|
|
|
|
) -> Result<TextureFormat, TextureError> {
|
|
|
|
if let Some(format) = ktx2.header().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)
|
2022-10-28 21:03:01 +00:00
|
|
|
.map_err(|err| TextureError::InvalidData(format!("KTX2: {err:?}")))?;
|
2022-03-15 22:26:46 +00:00
|
|
|
let sample_information = basic_data_format_descriptor
|
|
|
|
.sample_information()
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
return ktx2_dfd_to_texture_format(
|
|
|
|
&basic_data_format_descriptor,
|
|
|
|
&sample_information,
|
|
|
|
is_srgb,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Unknown".to_string(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
enum DataType {
|
|
|
|
Unorm,
|
|
|
|
UnormSrgb,
|
|
|
|
Snorm,
|
|
|
|
Float,
|
|
|
|
Uint,
|
|
|
|
Sint,
|
|
|
|
}
|
|
|
|
|
2024-09-27 00:59:59 +00:00
|
|
|
// This can be obtained from core::mem::transmute::<f32, u32>(1.0f32). It is used for identifying
|
2022-03-15 22:26:46 +00:00
|
|
|
// normalized sample types as in Unorm or Snorm.
|
|
|
|
const F32_1_AS_U32: u32 = 1065353216;
|
|
|
|
|
|
|
|
fn sample_information_to_data_type(
|
|
|
|
sample: &SampleInformation,
|
|
|
|
is_srgb: bool,
|
|
|
|
) -> Result<DataType, TextureError> {
|
|
|
|
// Exponent flag not supported
|
|
|
|
if sample
|
|
|
|
.channel_type_qualifiers
|
|
|
|
.contains(ChannelTypeQualifiers::EXPONENT)
|
|
|
|
{
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Unsupported KTX2 channel type qualifier: exponent".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
Ok(
|
|
|
|
if sample
|
|
|
|
.channel_type_qualifiers
|
|
|
|
.contains(ChannelTypeQualifiers::FLOAT)
|
|
|
|
{
|
|
|
|
// If lower bound of range is 0 then unorm, else if upper bound is 1.0f32 as u32
|
|
|
|
if sample
|
|
|
|
.channel_type_qualifiers
|
|
|
|
.contains(ChannelTypeQualifiers::SIGNED)
|
|
|
|
{
|
|
|
|
if sample.upper == F32_1_AS_U32 {
|
|
|
|
DataType::Snorm
|
|
|
|
} else {
|
|
|
|
DataType::Float
|
|
|
|
}
|
|
|
|
} else if is_srgb {
|
|
|
|
DataType::UnormSrgb
|
|
|
|
} else {
|
|
|
|
DataType::Unorm
|
|
|
|
}
|
|
|
|
} else if sample
|
|
|
|
.channel_type_qualifiers
|
|
|
|
.contains(ChannelTypeQualifiers::SIGNED)
|
|
|
|
{
|
|
|
|
DataType::Sint
|
|
|
|
} else {
|
|
|
|
DataType::Uint
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
Add feature requirement info to image loading docs (#13712)
# Objective
- Add "Available on crate feature <image format> only." for docs of
image format related types/functions
- Add warning "WARN bevy_render::texture::image: feature "<image
format>" is not enabled" on load attempt
- Fixes #13468 .
## Solution
- Added #[cfg(feature = "<image format>")] for types and warn!("feature
\"<image format>\" is not enabled"); for ImageFormat enum conversions
## Testing
ran reproducing example from issue #13468 and saw in logs
`WARN bevy_render::texture::image: feature "exr" is not enabled`
generated docs with command `RUSTDOCFLAGS="-Zunstable-options
--cfg=docsrs" cargo +nightly doc --workspace --all-features --no-deps
--document-private-items --open` and saw
![image](https://github.com/bevyengine/bevy/assets/17225606/820262bb-b4e6-4a5e-a306-bddbe9c40852)
that docs contain `Available on crate feature <image format> only.`
marks
![image](https://github.com/bevyengine/bevy/assets/17225606/57463440-a2ea-435f-a2c2-50d34f7f55a9)
## Migration Guide
Image format related entities are feature gated, if there are
compilation errors about unknown names there are some of features in
list (`exr`, `hdr`, `basis-universal`, `png`, `dds`, `tga`, `jpeg`,
`bmp`, `ktx2`, `webp` and `pnm`) should be added.
2024-08-16 23:43:20 +00:00
|
|
|
#[cfg(feature = "ktx2")]
|
2022-03-15 22:26:46 +00:00
|
|
|
pub fn ktx2_dfd_to_texture_format(
|
|
|
|
data_format_descriptor: &BasicDataFormatDescriptor,
|
|
|
|
sample_information: &[SampleInformation],
|
|
|
|
is_srgb: bool,
|
|
|
|
) -> Result<TextureFormat, TextureError> {
|
|
|
|
Ok(match data_format_descriptor.color_model {
|
|
|
|
Some(ColorModel::RGBSDA) => {
|
|
|
|
match sample_information.len() {
|
|
|
|
1 => {
|
|
|
|
// Only red channel allowed
|
|
|
|
if sample_information[0].channel_type != 0 {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Only red-component single-component KTX2 RGBSDA formats supported"
|
|
|
|
.to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
let sample = &sample_information[0];
|
|
|
|
let data_type = sample_information_to_data_type(sample, false)?;
|
|
|
|
match sample.bit_length {
|
|
|
|
8 => match data_type {
|
|
|
|
DataType::Unorm => TextureFormat::R8Unorm,
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for R8".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => TextureFormat::R8Snorm,
|
|
|
|
DataType::Float => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Float not supported for R8".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Uint => TextureFormat::R8Uint,
|
|
|
|
DataType::Sint => TextureFormat::R8Sint,
|
|
|
|
},
|
|
|
|
16 => match data_type {
|
|
|
|
DataType::Unorm => TextureFormat::R16Unorm,
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for R16".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => TextureFormat::R16Snorm,
|
|
|
|
DataType::Float => TextureFormat::R16Float,
|
|
|
|
DataType::Uint => TextureFormat::R16Uint,
|
|
|
|
DataType::Sint => TextureFormat::R16Sint,
|
|
|
|
},
|
|
|
|
32 => match data_type {
|
|
|
|
DataType::Unorm => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Unorm not supported for R32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for R32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Snorm not supported for R32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Float => TextureFormat::R32Float,
|
|
|
|
DataType::Uint => TextureFormat::R32Uint,
|
|
|
|
DataType::Sint => TextureFormat::R32Sint,
|
|
|
|
},
|
|
|
|
v => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Unsupported sample bit length for RGBSDA 1-channel format: {v}",
|
2022-03-15 22:26:46 +00:00
|
|
|
)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
2 => {
|
|
|
|
// Only red and green channels allowed
|
|
|
|
if sample_information[0].channel_type != 0
|
|
|
|
|| sample_information[1].channel_type != 1
|
|
|
|
{
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Only red-green-component two-component KTX2 RGBSDA formats supported"
|
|
|
|
.to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
// Only same bit length for all channels
|
|
|
|
assert_eq!(
|
|
|
|
sample_information[0].bit_length,
|
|
|
|
sample_information[1].bit_length
|
|
|
|
);
|
|
|
|
// Only same channel type qualifiers for all channels
|
|
|
|
assert_eq!(
|
|
|
|
sample_information[0].channel_type_qualifiers,
|
|
|
|
sample_information[1].channel_type_qualifiers
|
|
|
|
);
|
|
|
|
// Only same sample range for all channels
|
|
|
|
assert_eq!(sample_information[0].lower, sample_information[1].lower);
|
|
|
|
assert_eq!(sample_information[0].upper, sample_information[1].upper);
|
|
|
|
|
|
|
|
let sample = &sample_information[0];
|
|
|
|
let data_type = sample_information_to_data_type(sample, false)?;
|
|
|
|
match sample.bit_length {
|
|
|
|
8 => match data_type {
|
|
|
|
DataType::Unorm => TextureFormat::Rg8Unorm,
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for Rg8".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => TextureFormat::Rg8Snorm,
|
|
|
|
DataType::Float => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Float not supported for Rg8".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Uint => TextureFormat::Rg8Uint,
|
|
|
|
DataType::Sint => TextureFormat::Rg8Sint,
|
|
|
|
},
|
|
|
|
16 => match data_type {
|
|
|
|
DataType::Unorm => TextureFormat::Rg16Unorm,
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for Rg16".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => TextureFormat::Rg16Snorm,
|
|
|
|
DataType::Float => TextureFormat::Rg16Float,
|
|
|
|
DataType::Uint => TextureFormat::Rg16Uint,
|
|
|
|
DataType::Sint => TextureFormat::Rg16Sint,
|
|
|
|
},
|
|
|
|
32 => match data_type {
|
|
|
|
DataType::Unorm => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Unorm not supported for Rg32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for Rg32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Snorm not supported for Rg32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Float => TextureFormat::Rg32Float,
|
|
|
|
DataType::Uint => TextureFormat::Rg32Uint,
|
|
|
|
DataType::Sint => TextureFormat::Rg32Sint,
|
|
|
|
},
|
|
|
|
v => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Unsupported sample bit length for RGBSDA 2-channel format: {v}",
|
2022-03-15 22:26:46 +00:00
|
|
|
)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
3 => {
|
|
|
|
if sample_information[0].channel_type == 0
|
|
|
|
&& sample_information[0].bit_length == 11
|
|
|
|
&& sample_information[1].channel_type == 1
|
|
|
|
&& sample_information[1].bit_length == 11
|
|
|
|
&& sample_information[2].channel_type == 2
|
|
|
|
&& sample_information[2].bit_length == 10
|
|
|
|
{
|
2024-11-05 21:18:48 +00:00
|
|
|
TextureFormat::Rg11b10Ufloat
|
2022-03-15 22:26:46 +00:00
|
|
|
} else if sample_information[0].channel_type == 0
|
|
|
|
&& sample_information[0].bit_length == 9
|
|
|
|
&& sample_information[1].channel_type == 1
|
|
|
|
&& sample_information[1].bit_length == 9
|
|
|
|
&& sample_information[2].channel_type == 2
|
|
|
|
&& sample_information[2].bit_length == 9
|
|
|
|
{
|
|
|
|
TextureFormat::Rgb9e5Ufloat
|
|
|
|
} else if sample_information[0].channel_type == 0
|
|
|
|
&& sample_information[0].bit_length == 8
|
|
|
|
&& sample_information[1].channel_type == 1
|
|
|
|
&& sample_information[1].bit_length == 8
|
|
|
|
&& sample_information[2].channel_type == 2
|
|
|
|
&& sample_information[2].bit_length == 8
|
|
|
|
{
|
|
|
|
return Err(TextureError::FormatRequiresTranscodingError(
|
|
|
|
TranscodeFormat::Rgb8,
|
|
|
|
));
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"3-component formats not supported".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
4 => {
|
|
|
|
// Only RGBA or BGRA channels allowed
|
|
|
|
let is_rgba = sample_information[0].channel_type == 0;
|
|
|
|
assert!(
|
|
|
|
sample_information[0].channel_type == 0
|
|
|
|
|| sample_information[0].channel_type == 2
|
|
|
|
);
|
|
|
|
assert_eq!(sample_information[1].channel_type, 1);
|
|
|
|
assert_eq!(
|
|
|
|
sample_information[2].channel_type,
|
|
|
|
if is_rgba { 2 } else { 0 }
|
|
|
|
);
|
|
|
|
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
|
|
|
|
{
|
|
|
|
return Ok(TextureFormat::Rgb10a2Unorm);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only same bit length for all channels
|
|
|
|
assert!(
|
|
|
|
sample_information[0].bit_length == sample_information[1].bit_length
|
|
|
|
&& sample_information[0].bit_length == sample_information[2].bit_length
|
|
|
|
&& sample_information[0].bit_length == sample_information[3].bit_length
|
|
|
|
);
|
|
|
|
assert!(
|
|
|
|
sample_information[0].lower == sample_information[1].lower
|
|
|
|
&& sample_information[0].lower == sample_information[2].lower
|
|
|
|
&& sample_information[0].lower == sample_information[3].lower
|
|
|
|
);
|
|
|
|
assert!(
|
|
|
|
sample_information[0].upper == sample_information[1].upper
|
|
|
|
&& sample_information[0].upper == sample_information[2].upper
|
|
|
|
&& sample_information[0].upper == sample_information[3].upper
|
|
|
|
);
|
|
|
|
|
|
|
|
let sample = &sample_information[0];
|
|
|
|
let data_type = sample_information_to_data_type(sample, is_srgb)?;
|
|
|
|
match sample.bit_length {
|
|
|
|
8 => match data_type {
|
|
|
|
DataType::Unorm => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba8Unorm
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bgra8Unorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bgra8UnormSrgb
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::Snorm => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba8Snorm
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra8 not supported for Snorm".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::Float => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Float not supported for Rgba8/Bgra8".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Uint => {
|
|
|
|
if is_rgba {
|
|
|
|
// NOTE: This is more about how you want to use the data so
|
|
|
|
// TextureFormat::Rgba8Uint is incorrect here
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Rgba8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Rgba8Unorm
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra8 not supported for Uint".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::Sint => {
|
|
|
|
if is_rgba {
|
|
|
|
// NOTE: This is more about how you want to use the data so
|
|
|
|
// TextureFormat::Rgba8Sint is incorrect here
|
|
|
|
TextureFormat::Rgba8Snorm
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra8 not supported for Sint".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
16 => match data_type {
|
|
|
|
DataType::Unorm => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba16Unorm
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra16 not supported for Unorm".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for Rgba16/Bgra16".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba16Snorm
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra16 not supported for Snorm".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::Float => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba16Float
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra16 not supported for Float".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::Uint => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba16Uint
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra16 not supported for Uint".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::Sint => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba16Sint
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra16 not supported for Sint".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
32 => match data_type {
|
|
|
|
DataType::Unorm => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Unorm not supported for Rgba32/Bgra32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for Rgba32/Bgra32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Snorm not supported for Rgba32/Bgra32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Float => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba32Float
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra32 not supported for Float".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::Uint => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba32Uint
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra32 not supported for Uint".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DataType::Sint => {
|
|
|
|
if is_rgba {
|
|
|
|
TextureFormat::Rgba32Sint
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Bgra32 not supported for Sint".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
v => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Unsupported sample bit length for RGBSDA 4-channel format: {v}",
|
2022-03-15 22:26:46 +00:00
|
|
|
)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Unsupported channel count for RGBSDA format: {v}",
|
2022-03-15 22:26:46 +00:00
|
|
|
)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
Some(ColorModel::YUVSDA)
|
|
|
|
| Some(ColorModel::YIQSDA)
|
|
|
|
| Some(ColorModel::LabSDA)
|
|
|
|
| Some(ColorModel::CMYKA)
|
|
|
|
| Some(ColorModel::HSVAAng)
|
|
|
|
| Some(ColorModel::HSLAAng)
|
|
|
|
| Some(ColorModel::HSVAHex)
|
|
|
|
| Some(ColorModel::HSLAHex)
|
|
|
|
| Some(ColorModel::YCgCoA)
|
|
|
|
| Some(ColorModel::YcCbcCrc)
|
|
|
|
| Some(ColorModel::ICtCp)
|
|
|
|
| Some(ColorModel::CIEXYZ)
|
|
|
|
| Some(ColorModel::CIEXYY) => {
|
2022-03-15 22:26:46 +00:00
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
|
|
|
"{:?}",
|
|
|
|
data_format_descriptor.color_model
|
|
|
|
)));
|
|
|
|
}
|
|
|
|
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,
|
|
|
|
sample_information.len()
|
|
|
|
);
|
|
|
|
match sample_information.len() {
|
|
|
|
4 => {
|
|
|
|
// Only RGBA or BGRA channels allowed
|
|
|
|
assert_eq!(sample_information[0].channel_type, 0);
|
|
|
|
assert_eq!(sample_information[1].channel_type, 1);
|
|
|
|
assert_eq!(sample_information[2].channel_type, 2);
|
|
|
|
assert_eq!(sample_information[3].channel_type, 3);
|
|
|
|
// Only same bit length for all channels
|
|
|
|
assert!(
|
|
|
|
sample_information[0].bit_length == sample_information[1].bit_length
|
|
|
|
&& sample_information[0].bit_length == sample_information[2].bit_length
|
|
|
|
&& sample_information[0].bit_length == sample_information[3].bit_length
|
|
|
|
);
|
|
|
|
// Only same channel type qualifiers for all channels
|
|
|
|
assert!(
|
|
|
|
sample_information[0].channel_type_qualifiers
|
|
|
|
== sample_information[1].channel_type_qualifiers
|
|
|
|
&& sample_information[0].channel_type_qualifiers
|
|
|
|
== sample_information[2].channel_type_qualifiers
|
|
|
|
&& sample_information[0].channel_type_qualifiers
|
|
|
|
== sample_information[3].channel_type_qualifiers
|
|
|
|
);
|
|
|
|
// Only same sample range for all channels
|
|
|
|
assert!(
|
|
|
|
sample_information[0].lower == sample_information[1].lower
|
|
|
|
&& sample_information[0].lower == sample_information[2].lower
|
|
|
|
&& sample_information[0].lower == sample_information[3].lower
|
|
|
|
);
|
|
|
|
assert!(
|
|
|
|
sample_information[0].upper == sample_information[1].upper
|
|
|
|
&& sample_information[0].upper == sample_information[2].upper
|
|
|
|
&& sample_information[0].upper == sample_information[3].upper
|
|
|
|
);
|
|
|
|
|
|
|
|
let sample = &sample_information[0];
|
|
|
|
let data_type = sample_information_to_data_type(sample, false)?;
|
|
|
|
match sample.bit_length {
|
|
|
|
8 => match data_type {
|
|
|
|
DataType::Unorm => TextureFormat::Rgba8Unorm,
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for XYZW".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => TextureFormat::Rgba8Snorm,
|
|
|
|
DataType::Float => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Float not supported for Rgba8/Bgra8".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Uint => TextureFormat::Rgba8Uint,
|
|
|
|
DataType::Sint => TextureFormat::Rgba8Sint,
|
|
|
|
},
|
|
|
|
16 => match data_type {
|
|
|
|
DataType::Unorm => TextureFormat::Rgba16Unorm,
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for Rgba16/Bgra16".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => TextureFormat::Rgba16Snorm,
|
|
|
|
DataType::Float => TextureFormat::Rgba16Float,
|
|
|
|
DataType::Uint => TextureFormat::Rgba16Uint,
|
|
|
|
DataType::Sint => TextureFormat::Rgba16Sint,
|
|
|
|
},
|
|
|
|
32 => match data_type {
|
|
|
|
DataType::Unorm => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Unorm not supported for Rgba32/Bgra32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::UnormSrgb => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"UnormSrgb not supported for Rgba32/Bgra32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Snorm => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Snorm not supported for Rgba32/Bgra32".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
DataType::Float => TextureFormat::Rgba32Float,
|
|
|
|
DataType::Uint => TextureFormat::Rgba32Uint,
|
|
|
|
DataType::Sint => TextureFormat::Rgba32Sint,
|
|
|
|
},
|
|
|
|
v => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Unsupported sample bit length for XYZW 4-channel format: {v}",
|
2022-03-15 22:26:46 +00:00
|
|
|
)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Unsupported channel count for XYZW format: {v}",
|
2022-03-15 22:26:46 +00:00
|
|
|
)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ColorModel::BC1A) => {
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bc1RgbaUnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc1RgbaUnorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ColorModel::BC2) => {
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bc2RgbaUnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc2RgbaUnorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ColorModel::BC3) => {
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bc3RgbaUnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc3RgbaUnorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ColorModel::BC4) => {
|
|
|
|
if sample_information[0].lower == 0 {
|
|
|
|
TextureFormat::Bc4RUnorm
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc4RSnorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// FIXME: Red and green channels can be swapped for ATI2n/3Dc
|
|
|
|
Some(ColorModel::BC5) => {
|
|
|
|
if sample_information[0].lower == 0 {
|
|
|
|
TextureFormat::Bc5RgUnorm
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc5RgSnorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ColorModel::BC6H) => {
|
|
|
|
if sample_information[0].lower == 0 {
|
|
|
|
TextureFormat::Bc6hRgbUfloat
|
|
|
|
} else {
|
2023-04-26 15:34:23 +00:00
|
|
|
TextureFormat::Bc6hRgbFloat
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ColorModel::BC7) => {
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bc7RgbaUnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc7RgbaUnorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// ETC1 a subset of ETC2 only supporting Rgb8
|
|
|
|
Some(ColorModel::ETC1) => {
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Etc2Rgb8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Etc2Rgb8Unorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(ColorModel::ETC2) => match sample_information.len() {
|
|
|
|
1 => {
|
|
|
|
let sample = &sample_information[0];
|
|
|
|
match sample.channel_type {
|
|
|
|
0 => {
|
|
|
|
if sample_information[0]
|
|
|
|
.channel_type_qualifiers
|
|
|
|
.contains(ChannelTypeQualifiers::SIGNED)
|
|
|
|
{
|
|
|
|
TextureFormat::EacR11Snorm
|
|
|
|
} else {
|
|
|
|
TextureFormat::EacR11Unorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
2 => {
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Etc2Rgb8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Etc2Rgb8Unorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
|
|
|
"Invalid ETC2 sample channel type: {}",
|
|
|
|
sample.channel_type
|
|
|
|
)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
2 => {
|
|
|
|
let sample0 = &sample_information[0];
|
|
|
|
let sample1 = &sample_information[1];
|
|
|
|
if sample0.channel_type == 0 && sample1.channel_type == 1 {
|
|
|
|
if sample0
|
|
|
|
.channel_type_qualifiers
|
|
|
|
.contains(ChannelTypeQualifiers::SIGNED)
|
|
|
|
{
|
|
|
|
TextureFormat::EacRg11Snorm
|
|
|
|
} else {
|
|
|
|
TextureFormat::EacRg11Unorm
|
|
|
|
}
|
|
|
|
} else if sample0.channel_type == 2 && sample1.channel_type == 15 {
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Etc2Rgb8A1UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Etc2Rgb8A1Unorm
|
|
|
|
}
|
|
|
|
} else if sample0.channel_type == 15 && sample1.channel_type == 2 {
|
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Etc2Rgba8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Etc2Rgba8Unorm
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
|
|
|
"Invalid ETC2 2-sample channel types: {} {}",
|
|
|
|
sample0.channel_type, sample1.channel_type
|
|
|
|
)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Unsupported channel count for ETC2 format: {v}",
|
2022-03-15 22:26:46 +00:00
|
|
|
)));
|
|
|
|
}
|
|
|
|
},
|
2022-07-14 21:17:16 +00:00
|
|
|
Some(ColorModel::ASTC) => TextureFormat::Astc {
|
|
|
|
block: match (
|
|
|
|
data_format_descriptor.texel_block_dimensions[0],
|
|
|
|
data_format_descriptor.texel_block_dimensions[1],
|
|
|
|
) {
|
|
|
|
(4, 4) => AstcBlock::B4x4,
|
|
|
|
(5, 4) => AstcBlock::B5x4,
|
|
|
|
(5, 5) => AstcBlock::B5x5,
|
|
|
|
(6, 5) => AstcBlock::B6x5,
|
|
|
|
(8, 5) => AstcBlock::B8x5,
|
|
|
|
(8, 8) => AstcBlock::B8x8,
|
|
|
|
(10, 5) => AstcBlock::B10x5,
|
|
|
|
(10, 6) => AstcBlock::B10x6,
|
|
|
|
(10, 8) => AstcBlock::B10x8,
|
|
|
|
(10, 10) => AstcBlock::B10x10,
|
|
|
|
(12, 10) => AstcBlock::B12x10,
|
|
|
|
(12, 12) => AstcBlock::B12x12,
|
2022-03-15 22:26:46 +00:00
|
|
|
d => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2022-07-14 21:17:16 +00:00
|
|
|
"Invalid ASTC dimension: {} x {}",
|
|
|
|
d.0, d.1
|
2022-03-15 22:26:46 +00:00
|
|
|
)))
|
|
|
|
}
|
|
|
|
},
|
2022-07-14 21:17:16 +00:00
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
2022-03-15 22:26:46 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
Some(ColorModel::ETC1S) => {
|
|
|
|
return Err(TextureError::FormatRequiresTranscodingError(
|
|
|
|
TranscodeFormat::Etc1s,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
Some(ColorModel::PVRTC) => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"PVRTC is not supported".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
Some(ColorModel::PVRTC2) => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"PVRTC2 is not supported".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
Some(ColorModel::UASTC) => {
|
|
|
|
return Err(TextureError::FormatRequiresTranscodingError(
|
2022-06-17 00:14:02 +00:00
|
|
|
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!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"Invalid KTX2 UASTC channel type: {channel_type}",
|
2022-06-17 00:14:02 +00:00
|
|
|
)))
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(
|
|
|
|
"Unspecified KTX2 color model".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
|
|
|
"Unknown KTX2 color model: {:?}",
|
|
|
|
data_format_descriptor.color_model
|
|
|
|
)));
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
Add feature requirement info to image loading docs (#13712)
# Objective
- Add "Available on crate feature <image format> only." for docs of
image format related types/functions
- Add warning "WARN bevy_render::texture::image: feature "<image
format>" is not enabled" on load attempt
- Fixes #13468 .
## Solution
- Added #[cfg(feature = "<image format>")] for types and warn!("feature
\"<image format>\" is not enabled"); for ImageFormat enum conversions
## Testing
ran reproducing example from issue #13468 and saw in logs
`WARN bevy_render::texture::image: feature "exr" is not enabled`
generated docs with command `RUSTDOCFLAGS="-Zunstable-options
--cfg=docsrs" cargo +nightly doc --workspace --all-features --no-deps
--document-private-items --open` and saw
![image](https://github.com/bevyengine/bevy/assets/17225606/820262bb-b4e6-4a5e-a306-bddbe9c40852)
that docs contain `Available on crate feature <image format> only.`
marks
![image](https://github.com/bevyengine/bevy/assets/17225606/57463440-a2ea-435f-a2c2-50d34f7f55a9)
## Migration Guide
Image format related entities are feature gated, if there are
compilation errors about unknown names there are some of features in
list (`exr`, `hdr`, `basis-universal`, `png`, `dds`, `tga`, `jpeg`,
`bmp`, `ktx2`, `webp` and `pnm`) should be added.
2024-08-16 23:43:20 +00:00
|
|
|
#[cfg(feature = "ktx2")]
|
2022-03-15 22:26:46 +00:00
|
|
|
pub fn ktx2_format_to_texture_format(
|
|
|
|
ktx2_format: ktx2::Format,
|
|
|
|
is_srgb: bool,
|
|
|
|
) -> Result<TextureFormat, TextureError> {
|
|
|
|
Ok(match ktx2_format {
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::R8_UNORM | ktx2::Format::R8_SRGB => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
Fix KTX2 R8_SRGB, R8_UNORM, R8G8_SRGB, R8G8_UNORM, R8G8B8_SRGB, R8G8B8_UNORM support (#4594)
# Objective
- Fixes #4592
## Solution
- Implement `SrgbColorSpace` for `u8` via `f32`
- Convert KTX2 R8 and R8G8 non-linear sRGB to wgpu `R8Unorm` and `Rg8Unorm` as non-linear sRGB are not supported by wgpu for these formats
- Convert KTX2 R8G8B8 formats to `Rgba8Unorm` and `Rgba8UnormSrgb` by adding an alpha channel as the Rgb variants don't exist in wgpu
---
## Changelog
- Added: Support for KTX2 `R8_SRGB`, `R8_UNORM`, `R8G8_SRGB`, `R8G8_UNORM`, `R8G8B8_SRGB`, `R8G8B8_UNORM` formats by converting to supported wgpu formats as appropriate
2023-01-30 09:04:08 +00:00
|
|
|
return Err(TextureError::FormatRequiresTranscodingError(
|
|
|
|
TranscodeFormat::R8UnormSrgb,
|
|
|
|
));
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
TextureFormat::R8Unorm
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
ktx2::Format::R8_SNORM => TextureFormat::R8Snorm,
|
|
|
|
ktx2::Format::R8_UINT => TextureFormat::R8Uint,
|
|
|
|
ktx2::Format::R8_SINT => TextureFormat::R8Sint,
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::R8G8_UNORM | ktx2::Format::R8G8_SRGB => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
Fix KTX2 R8_SRGB, R8_UNORM, R8G8_SRGB, R8G8_UNORM, R8G8B8_SRGB, R8G8B8_UNORM support (#4594)
# Objective
- Fixes #4592
## Solution
- Implement `SrgbColorSpace` for `u8` via `f32`
- Convert KTX2 R8 and R8G8 non-linear sRGB to wgpu `R8Unorm` and `Rg8Unorm` as non-linear sRGB are not supported by wgpu for these formats
- Convert KTX2 R8G8B8 formats to `Rgba8Unorm` and `Rgba8UnormSrgb` by adding an alpha channel as the Rgb variants don't exist in wgpu
---
## Changelog
- Added: Support for KTX2 `R8_SRGB`, `R8_UNORM`, `R8G8_SRGB`, `R8G8_UNORM`, `R8G8B8_SRGB`, `R8G8B8_UNORM` formats by converting to supported wgpu formats as appropriate
2023-01-30 09:04:08 +00:00
|
|
|
return Err(TextureError::FormatRequiresTranscodingError(
|
|
|
|
TranscodeFormat::Rg8UnormSrgb,
|
|
|
|
));
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
TextureFormat::Rg8Unorm
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
ktx2::Format::R8G8_SNORM => TextureFormat::Rg8Snorm,
|
|
|
|
ktx2::Format::R8G8_UINT => TextureFormat::Rg8Uint,
|
|
|
|
ktx2::Format::R8G8_SINT => TextureFormat::Rg8Sint,
|
Fix KTX2 R8_SRGB, R8_UNORM, R8G8_SRGB, R8G8_UNORM, R8G8B8_SRGB, R8G8B8_UNORM support (#4594)
# Objective
- Fixes #4592
## Solution
- Implement `SrgbColorSpace` for `u8` via `f32`
- Convert KTX2 R8 and R8G8 non-linear sRGB to wgpu `R8Unorm` and `Rg8Unorm` as non-linear sRGB are not supported by wgpu for these formats
- Convert KTX2 R8G8B8 formats to `Rgba8Unorm` and `Rgba8UnormSrgb` by adding an alpha channel as the Rgb variants don't exist in wgpu
---
## Changelog
- Added: Support for KTX2 `R8_SRGB`, `R8_UNORM`, `R8G8_SRGB`, `R8G8_UNORM`, `R8G8B8_SRGB`, `R8G8B8_UNORM` formats by converting to supported wgpu formats as appropriate
2023-01-30 09:04:08 +00:00
|
|
|
ktx2::Format::R8G8B8_UNORM | ktx2::Format::R8G8B8_SRGB => {
|
|
|
|
return Err(TextureError::FormatRequiresTranscodingError(
|
|
|
|
TranscodeFormat::Rgb8,
|
|
|
|
));
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::R8G8B8A8_UNORM | ktx2::Format::R8G8B8A8_SRGB => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Rgba8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Rgba8Unorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ktx2::Format::R8G8B8A8_SNORM => TextureFormat::Rgba8Snorm,
|
|
|
|
ktx2::Format::R8G8B8A8_UINT => TextureFormat::Rgba8Uint,
|
|
|
|
ktx2::Format::R8G8B8A8_SINT => TextureFormat::Rgba8Sint,
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::B8G8R8A8_UNORM | ktx2::Format::B8G8R8A8_SRGB => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bgra8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bgra8Unorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ktx2::Format::A2R10G10B10_UNORM_PACK32 => TextureFormat::Rgb10a2Unorm,
|
|
|
|
|
|
|
|
ktx2::Format::R16_UNORM => TextureFormat::R16Unorm,
|
|
|
|
ktx2::Format::R16_SNORM => TextureFormat::R16Snorm,
|
|
|
|
ktx2::Format::R16_UINT => TextureFormat::R16Uint,
|
|
|
|
ktx2::Format::R16_SINT => TextureFormat::R16Sint,
|
|
|
|
ktx2::Format::R16_SFLOAT => TextureFormat::R16Float,
|
|
|
|
ktx2::Format::R16G16_UNORM => TextureFormat::Rg16Unorm,
|
|
|
|
ktx2::Format::R16G16_SNORM => TextureFormat::Rg16Snorm,
|
|
|
|
ktx2::Format::R16G16_UINT => TextureFormat::Rg16Uint,
|
|
|
|
ktx2::Format::R16G16_SINT => TextureFormat::Rg16Sint,
|
|
|
|
ktx2::Format::R16G16_SFLOAT => TextureFormat::Rg16Float,
|
|
|
|
|
|
|
|
ktx2::Format::R16G16B16A16_UNORM => TextureFormat::Rgba16Unorm,
|
|
|
|
ktx2::Format::R16G16B16A16_SNORM => TextureFormat::Rgba16Snorm,
|
|
|
|
ktx2::Format::R16G16B16A16_UINT => TextureFormat::Rgba16Uint,
|
|
|
|
ktx2::Format::R16G16B16A16_SINT => TextureFormat::Rgba16Sint,
|
|
|
|
ktx2::Format::R16G16B16A16_SFLOAT => TextureFormat::Rgba16Float,
|
|
|
|
ktx2::Format::R32_UINT => TextureFormat::R32Uint,
|
|
|
|
ktx2::Format::R32_SINT => TextureFormat::R32Sint,
|
|
|
|
ktx2::Format::R32_SFLOAT => TextureFormat::R32Float,
|
|
|
|
ktx2::Format::R32G32_UINT => TextureFormat::Rg32Uint,
|
|
|
|
ktx2::Format::R32G32_SINT => TextureFormat::Rg32Sint,
|
|
|
|
ktx2::Format::R32G32_SFLOAT => TextureFormat::Rg32Float,
|
|
|
|
|
|
|
|
ktx2::Format::R32G32B32A32_UINT => TextureFormat::Rgba32Uint,
|
|
|
|
ktx2::Format::R32G32B32A32_SINT => TextureFormat::Rgba32Sint,
|
|
|
|
ktx2::Format::R32G32B32A32_SFLOAT => TextureFormat::Rgba32Float,
|
|
|
|
|
2024-11-05 21:18:48 +00:00
|
|
|
ktx2::Format::B10G11R11_UFLOAT_PACK32 => TextureFormat::Rg11b10Ufloat,
|
2022-03-15 22:26:46 +00:00
|
|
|
ktx2::Format::E5B9G9R9_UFLOAT_PACK32 => TextureFormat::Rgb9e5Ufloat,
|
|
|
|
|
|
|
|
ktx2::Format::X8_D24_UNORM_PACK32 => TextureFormat::Depth24Plus,
|
|
|
|
ktx2::Format::D32_SFLOAT => TextureFormat::Depth32Float,
|
|
|
|
|
|
|
|
ktx2::Format::D24_UNORM_S8_UINT => TextureFormat::Depth24PlusStencil8,
|
|
|
|
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::BC1_RGB_UNORM_BLOCK
|
|
|
|
| ktx2::Format::BC1_RGB_SRGB_BLOCK
|
|
|
|
| ktx2::Format::BC1_RGBA_UNORM_BLOCK
|
|
|
|
| ktx2::Format::BC1_RGBA_SRGB_BLOCK => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bc1RgbaUnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc1RgbaUnorm
|
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::BC2_UNORM_BLOCK | ktx2::Format::BC2_SRGB_BLOCK => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bc2RgbaUnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc2RgbaUnorm
|
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::BC3_UNORM_BLOCK | ktx2::Format::BC3_SRGB_BLOCK => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bc3RgbaUnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc3RgbaUnorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ktx2::Format::BC4_UNORM_BLOCK => TextureFormat::Bc4RUnorm,
|
|
|
|
ktx2::Format::BC4_SNORM_BLOCK => TextureFormat::Bc4RSnorm,
|
|
|
|
ktx2::Format::BC5_UNORM_BLOCK => TextureFormat::Bc5RgUnorm,
|
|
|
|
ktx2::Format::BC5_SNORM_BLOCK => TextureFormat::Bc5RgSnorm,
|
|
|
|
ktx2::Format::BC6H_UFLOAT_BLOCK => TextureFormat::Bc6hRgbUfloat,
|
2023-04-26 15:34:23 +00:00
|
|
|
ktx2::Format::BC6H_SFLOAT_BLOCK => TextureFormat::Bc6hRgbFloat,
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::BC7_UNORM_BLOCK | ktx2::Format::BC7_SRGB_BLOCK => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Bc7RgbaUnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Bc7RgbaUnorm
|
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ETC2_R8G8B8_UNORM_BLOCK | ktx2::Format::ETC2_R8G8B8_SRGB_BLOCK => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Etc2Rgb8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Etc2Rgb8Unorm
|
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ETC2_R8G8B8A1_UNORM_BLOCK | ktx2::Format::ETC2_R8G8B8A1_SRGB_BLOCK => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Etc2Rgb8A1UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Etc2Rgb8A1Unorm
|
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ETC2_R8G8B8A8_UNORM_BLOCK | ktx2::Format::ETC2_R8G8B8A8_SRGB_BLOCK => {
|
2022-03-15 22:26:46 +00:00
|
|
|
if is_srgb {
|
|
|
|
TextureFormat::Etc2Rgba8UnormSrgb
|
|
|
|
} else {
|
|
|
|
TextureFormat::Etc2Rgba8Unorm
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ktx2::Format::EAC_R11_UNORM_BLOCK => TextureFormat::EacR11Unorm,
|
|
|
|
ktx2::Format::EAC_R11_SNORM_BLOCK => TextureFormat::EacR11Snorm,
|
|
|
|
ktx2::Format::EAC_R11G11_UNORM_BLOCK => TextureFormat::EacRg11Unorm,
|
|
|
|
ktx2::Format::EAC_R11G11_SNORM_BLOCK => TextureFormat::EacRg11Snorm,
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_4x4_UNORM_BLOCK | ktx2::Format::ASTC_4x4_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B4x4,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_5x4_UNORM_BLOCK | ktx2::Format::ASTC_5x4_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B5x4,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_5x5_UNORM_BLOCK | ktx2::Format::ASTC_5x5_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B5x5,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_6x5_UNORM_BLOCK | ktx2::Format::ASTC_6x5_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B6x5,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_6x6_UNORM_BLOCK | ktx2::Format::ASTC_6x6_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B6x6,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_8x5_UNORM_BLOCK | ktx2::Format::ASTC_8x5_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B8x5,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_8x6_UNORM_BLOCK | ktx2::Format::ASTC_8x6_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B8x6,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_8x8_UNORM_BLOCK | ktx2::Format::ASTC_8x8_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B8x8,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_10x5_UNORM_BLOCK | ktx2::Format::ASTC_10x5_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B10x5,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_10x6_UNORM_BLOCK | ktx2::Format::ASTC_10x6_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B10x6,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_10x8_UNORM_BLOCK | ktx2::Format::ASTC_10x8_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B10x8,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_10x10_UNORM_BLOCK | ktx2::Format::ASTC_10x10_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B10x10,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_12x10_UNORM_BLOCK | ktx2::Format::ASTC_12x10_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B12x10,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-31 01:38:07 +00:00
|
|
|
ktx2::Format::ASTC_12x12_UNORM_BLOCK | ktx2::Format::ASTC_12x12_SRGB_BLOCK => {
|
2022-07-14 21:17:16 +00:00
|
|
|
TextureFormat::Astc {
|
|
|
|
block: AstcBlock::B12x12,
|
|
|
|
channel: if is_srgb {
|
|
|
|
AstcChannel::UnormSrgb
|
|
|
|
} else {
|
|
|
|
AstcChannel::Unorm
|
|
|
|
},
|
2022-03-15 22:26:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
return Err(TextureError::UnsupportedTextureFormat(format!(
|
2023-01-11 09:51:22 +00:00
|
|
|
"{ktx2_format:?}"
|
2022-03-15 22:26:46 +00:00
|
|
|
)))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2024-04-14 14:40:10 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2024-10-04 20:16:47 +00:00
|
|
|
use crate::CompressedImageFormats;
|
2024-04-14 14:40:10 +00:00
|
|
|
|
|
|
|
use super::ktx2_buffer_to_image;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_ktx_levels() {
|
:pencil2: Fix typos across bevy (#16702)
# Objective
Fixes typos in bevy project, following suggestion in
https://github.com/bevyengine/bevy-website/pull/1912#pullrequestreview-2483499337
## Solution
I used https://github.com/crate-ci/typos to find them.
I included only the ones that feel undebatable too me, but I am not in
game engine so maybe some terms are expected.
I left out the following typos:
- `reparametrize` => `reparameterize`: There are a lot of occurences, I
believe this was expected
- `semicircles` => `hemicircles`: 2 occurences, may mean something
specific in geometry
- `invertation` => `inversion`: may mean something specific
- `unparented` => `parentless`: may mean something specific
- `metalness` => `metallicity`: may mean something specific
## Testing
- Did you test these changes? If so, how? I did not test the changes,
most changes are related to raw text. I expect the others to be tested
by the CI.
- Are there any parts that need more testing? I do not think
- How can other people (reviewers) test your changes? Is there anything
specific they need to know? To me there is nothing to test
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
---
## Migration Guide
> This section is optional. If there are no breaking changes, you can
delete this section.
(kept in case I include the `reparameterize` change here)
- If this PR is a breaking change (relative to the last release of
Bevy), describe how a user might need to migrate their code to support
these changes
- Simply adding new functionality is not a breaking change.
- Fixing behavior that was definitely a bug, rather than a questionable
design choice is not a breaking change.
## Questions
- [x] Should I include the above typos? No
(https://github.com/bevyengine/bevy/pull/16702#issuecomment-2525271152)
- [ ] Should I add `typos` to the CI? (I will check how to configure it
properly)
This project looks awesome, I really enjoy reading the progress made,
thanks to everyone involved.
2024-12-08 01:18:39 +00:00
|
|
|
// R8UnormSrgb texture with 4x4 pixels data and 3 levels of mipmaps
|
2024-04-14 14:40:10 +00:00
|
|
|
let buffer = vec![
|
|
|
|
0xab, 0x4b, 0x54, 0x58, 0x20, 0x32, 0x30, 0xbb, 0x0d, 10, 0x1a, 10, 0x0f, 0, 0, 0, 1,
|
|
|
|
0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0x98, 0, 0, 0, 0x2c, 0, 0, 0, 0xc4, 0, 0, 0, 0x5c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0x28, 1, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0x10,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0x24, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0x20, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0x2c, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0x28, 0, 1, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0x12, 0, 0, 0, 0x4b, 0x54, 0x58,
|
|
|
|
0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0, 0x72, 0x64, 0, 0,
|
|
|
|
0, 0x10, 0, 0, 0, 0x4b, 0x54, 0x58, 0x73, 0x77, 0x69, 0x7a, 0x7a, 0x6c, 0x65, 0, 0x72,
|
|
|
|
0x72, 0x72, 0x31, 0, 0x2c, 0, 0, 0, 0x4b, 0x54, 0x58, 0x77, 0x72, 0x69, 0x74, 0x65,
|
|
|
|
0x72, 0, 0x74, 0x6f, 0x6b, 0x74, 0x78, 0x20, 0x76, 0x34, 0x2e, 0x33, 0x2e, 0x30, 0x7e,
|
|
|
|
0x32, 0x38, 0x20, 0x2f, 0x20, 0x6c, 0x69, 0x62, 0x6b, 0x74, 0x78, 0x20, 0x76, 0x34,
|
|
|
|
0x2e, 0x33, 0x2e, 0x30, 0x7e, 0x31, 0, 0x4a, 0, 0, 0, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
|
|
|
|
0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
|
|
|
|
0x4a,
|
|
|
|
];
|
|
|
|
let supported_compressed_formats = CompressedImageFormats::empty();
|
|
|
|
let result = ktx2_buffer_to_image(&buffer, supported_compressed_formats, true);
|
|
|
|
assert!(result.is_ok());
|
|
|
|
}
|
|
|
|
}
|