Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.ktx2 filter=lfs diff=lfs merge=lfs -text
vendor/basis_universal/**/* filter=lfs diff=lfs merge=lfs -text
*.wasm filter=lfs diff=lfs merge=lfs -text
original_assets/**/* filter=lfs diff=lfs merge=lfs -text
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Unreleased

-
- Update basis universal to v2.1.0

## v0.4.2

Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ repository = "https://github.com/beicause/bevy_basisu_loader"
license = "MIT OR Apache-2.0"

[dependencies]
bevy_basisu_loader_sys = { version = "0.4", path = "crates/basisu_sys" }

bevy = { version = "0.18", default-features = false, features = [
"bevy_asset",
"bevy_image",
Expand All @@ -22,7 +24,6 @@ bevy = { version = "0.18", default-features = false, features = [
serde = { version = "1", features = ["derive"] }
thiserror = { version = "2", default-features = false }
log = { version = "0.4", default-features = false }
bevy_basisu_loader_sys = { version = "0.4", path = "crates/basisu_sys" }

[workspace]
members = ["crates/*", "examples/test_scene"]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ For web, it contains a tool to build vendored basisu using Emscripten and produc

| `bevy` | `bevy_basisu_loader` | `basis_universal` |
| ------ | -------------------- | ----------------- |
| 0.18 | 0.3, 0.4 | v2_0_2 |
| 0.18 | 0.3, 0.4 | v2_1_0 |
| 0.17 | 0.1, 0.2 | v1_60_snapshot |

## License
Expand Down
3 changes: 0 additions & 3 deletions assets/alpha0_etc1s.basisu.ktx2

This file was deleted.

3 changes: 3 additions & 0 deletions assets/alpha0_etc1s_mips.basisu.ktx2
Git LFS file not shown
3 changes: 3 additions & 0 deletions assets/desk_uastc_hdr_4x4.basisu.ktx2
Git LFS file not shown
3 changes: 0 additions & 3 deletions assets/desk_uastc_hdr_4x4_mips_10.basisu.ktx2

This file was deleted.

3 changes: 3 additions & 0 deletions assets/desk_uastc_hdr_6x6_mips.basisu.ktx2
Git LFS file not shown
3 changes: 0 additions & 3 deletions assets/desk_uastc_hdr_6x6_mips_10.basisu.ktx2

This file was deleted.

3 changes: 0 additions & 3 deletions assets/gl_skybox_etc1s_cubemap_mips_12.basisu.ktx2

This file was deleted.

3 changes: 0 additions & 3 deletions assets/gl_skybox_uastc_cubemap_mips_12.basisu.ktx2

This file was deleted.

3 changes: 0 additions & 3 deletions assets/kodim20_astc_ldr_8x8.basisu.ktx2

This file was deleted.

3 changes: 3 additions & 0 deletions assets/kodim20_astc_ldr_8x8_mips.basisu.ktx2
Git LFS file not shown
3 changes: 3 additions & 0 deletions assets/skybox_xuastc_ldr_8x8_cubemap_mips.basisu.ktx2
Git LFS file not shown
3 changes: 3 additions & 0 deletions assets/tough_uastc_ldr_4x4.basisu.ktx2
Git LFS file not shown
3 changes: 0 additions & 3 deletions assets/tough_uastc_ldr_4x4_mips_11.basisu.ktx2

This file was deleted.

3 changes: 0 additions & 3 deletions assets/wikipedia_xuastc_ldr_6x6.basisu.ktx2

This file was deleted.

3 changes: 3 additions & 0 deletions assets/wikipedia_xuastc_ldr_6x6_mips.basisu.ktx2
Git LFS file not shown
27 changes: 19 additions & 8 deletions crates/basisu_sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const FLAGS: &[&str] = &[
"-Werror",
"-fno-exceptions",
"-Wno-unused-function",
"-Wno-unused-const-variable",
Expand All @@ -7,6 +8,7 @@ const FLAGS: &[&str] = &[
"-Wno-unused-value",
"-Wno-deprecated",
"-Wno-type-limits",
"-Wno-stringop-overflow",
];
// Disable PVRTC1/2, ATC, FXT1 as wgpu does not support them.
const DEFINES: &[(&str, &str)] = &[
Expand Down Expand Up @@ -54,12 +56,19 @@ fn bindgen() {
.use_core()
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.allowlist_type("Transcoder")
.allowlist_type("TextureTranscodedFormat")
.allowlist_type("TranscodedTextureFormat")
.allowlist_type("BasisTextureFormat")
.allowlist_type("SupportedTextureCompressionMethods")
.allowlist_type("ChannelType")
.opaque_type("Transcoder")
.rustified_enum("TranscodedTextureFormat")
.rustified_enum("BasisTextureFormat")
.bitfield_enum("SupportedTextureCompressionMethods")
.rustified_enum("ChannelType")
.allowlist_function("c_basisu_transcoder_init")
.allowlist_function("c_ktx2_transcoder_new")
.allowlist_function("c_ktx2_transcoder_delete")
.allowlist_function("c_ktx2_transcoder_transcode_image")
.allowlist_function("c_ktx2_transcoder_transcode_image_alloc_dst")
.allowlist_function("c_ktx2_transcoder_get_r_dst_buf")
.allowlist_function("c_ktx2_transcoder_get_r_dst_buf_len")
.allowlist_function("c_ktx2_transcoder_get_r_width")
Expand All @@ -68,11 +77,10 @@ fn bindgen() {
.allowlist_function("c_ktx2_transcoder_get_r_layers")
.allowlist_function("c_ktx2_transcoder_get_r_faces")
.allowlist_function("c_ktx2_transcoder_get_r_target_format")
.allowlist_function("c_ktx2_transcoder_get_r_basis_format")
.allowlist_function("c_ktx2_transcoder_get_r_is_srgb")
.opaque_type("Transcoder")
.bitfield_enum("SupportedTextureCompressionMethods")
.rustified_enum("TextureTranscodedFormat")
.rustified_enum("ChannelType")
.allowlist_function("c_ktx2_transcoder_transcode_image_get_info")
.allowlist_function("c_ktx2_transcoder_transcode_image_write_buffer")
.generate()
.expect("Unable to generate bindings")
.write_to_file(binding_file)
Expand All @@ -93,6 +101,9 @@ fn compile_basisu_static() {
for (define, value) in DEFINES {
build.define(define, *value);
}
// FIXME: This works around a bug.
// With -O2 or -O3, the transcoded astc/uastc -> bcn textures have many artifacts, especially when -mipmap is enabled. But with -Os the results are much better.
build.opt_level_str("s");
build.files(SRCS).compile("basisu_vendor");
}

Expand All @@ -103,11 +114,11 @@ fn gen_wasm_build_cmd() {
"-sINCOMING_MODULE_JS_API=wasmBinary",
"-sALLOW_MEMORY_GROWTH",
"-sEXPORTED_RUNTIME_METHODS=HEAPU8",
"-sEXPORTED_FUNCTIONS=_malloc,_free,_c_basisu_transcoder_init,_c_ktx2_transcoder_new,_c_ktx2_transcoder_delete,_c_ktx2_transcoder_transcode_image,_c_ktx2_transcoder_get_r_dst_buf,_c_ktx2_transcoder_get_r_dst_buf_len,_c_ktx2_transcoder_get_r_width,_c_ktx2_transcoder_get_r_height,_c_ktx2_transcoder_get_r_levels,_c_ktx2_transcoder_get_r_layers,_c_ktx2_transcoder_get_r_faces,_c_ktx2_transcoder_get_r_target_format,_c_ktx2_transcoder_get_r_is_srgb",
"-sEXPORTED_FUNCTIONS=_malloc,_free,_c_basisu_transcoder_init,_c_ktx2_transcoder_new,_c_ktx2_transcoder_delete,_c_ktx2_transcoder_transcode_image_alloc_dst,_c_ktx2_transcoder_get_r_dst_buf,_c_ktx2_transcoder_get_r_dst_buf_len,_c_ktx2_transcoder_get_r_width,_c_ktx2_transcoder_get_r_height,_c_ktx2_transcoder_get_r_levels,_c_ktx2_transcoder_get_r_layers,_c_ktx2_transcoder_get_r_faces,_c_ktx2_transcoder_get_r_target_format,_c_ktx2_transcoder_get_r_basis_format,_c_ktx2_transcoder_get_r_is_srgb",
];
let mut cmd = std::process::Command::new("em++");
cmd.args(["-xc++", "-std=c++17"])
.args(FLAGS)
.args(FLAGS.iter().filter(|f| **f != "-Wno-stringop-overflow"))
.args(
DEFINES
.iter()
Expand Down
115 changes: 102 additions & 13 deletions crates/basisu_sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,18 @@ extern crate alloc;
non_camel_case_types,
reason = "Generated code is OK to have non upper case globals or non camel case enums"
)]
#[cfg_attr(
all(
target_arch = "wasm32",
target_vendor = "unknown",
target_os = "unknown"
),
expect(
unused,
reason = "On wasm32 we use js bindings thus native functions are expected to be unused"
)
#[expect(
unused,
reason = "On wasm32 we use js bindings thus all native functions are expected to be unused. \
On native `c_ktx2_transcoder_transcode_image_alloc_dst` and `c_ktx2_transcoder_get_r_dst_buf` are unused"
)]
mod transcoding {
include!(concat!(env!("OUT_DIR"), "/transcoding.rs"));
}

use alloc::vec::Vec;
pub use transcoding::{
ChannelType, SupportedTextureCompressionMethods, TextureTranscodedFormat, Transcoder,
BasisTextureFormat, ChannelType, SupportedTextureCompressionMethods, TranscodedTextureFormat,
};

#[cfg(not(all(
Expand All @@ -43,7 +38,7 @@ mod native;
target_vendor = "unknown",
target_os = "unknown",
)))]
pub use native::*;
use native::*;

#[cfg(all(
target_arch = "wasm32",
Expand All @@ -56,4 +51,98 @@ mod web;
target_vendor = "unknown",
target_os = "unknown",
))]
pub use web::*;
use web::*;

/// Init basisu global data. Must be called before transcoding.
pub async fn basisu_init() {
#[cfg(all(
target_arch = "wasm32",
target_vendor = "unknown",
target_os = "unknown",
))]
basisu_sys_init_vendor().await;
unsafe {
basisu_transcoder_init();
}
}

pub struct TranscodeResult {
pub data: Vec<u8>,
pub width: u32,
pub height: u32,
pub levels: u32,
pub layers: u32,
pub faces: u32,
pub is_srgb: bool,
pub basis_format: BasisTextureFormat,
pub target_format: TranscodedTextureFormat,
}

/// Transcode the basisu ktx2 data.
pub fn basisu_transcode(
data: Vec<u8>,
supported_compressed_formats: SupportedTextureCompressionMethods,
channel_type_hint: ChannelType,
force_transcode_target: TranscodedTextureFormat,
) -> Option<TranscodeResult> {
unsafe {
let transcoder = ktx2_transcoder_new();
#[cfg(all(
target_arch = "wasm32",
target_vendor = "unknown",
target_os = "unknown",
))]
let result = {
let success = ktx2_transcoder_transcode_image_alloc_dst(
transcoder,
data,
supported_compressed_formats,
channel_type_hint,
force_transcode_target,
);
if !success {
ktx2_transcoder_delete(transcoder);
return None;
}
ktx2_transcoder_get_r_dst_buf(transcoder)
};

#[cfg(not(all(
target_arch = "wasm32",
target_vendor = "unknown",
target_os = "unknown",
)))]
let result = {
let success = ktx2_transcoder_transcode_image_get_info(
transcoder,
data.as_ptr(),
u32::try_from(data.len()).unwrap(),
supported_compressed_formats,
channel_type_hint,
force_transcode_target,
);
if !success {
ktx2_transcoder_delete(transcoder);
return None;
}
let mut buffer =
alloc::vec![0u8; ktx2_transcoder_get_r_dst_buf_len(transcoder) as usize];
ktx2_transcoder_transcode_image_write_buffer(transcoder, buffer.as_mut_ptr());
buffer
};

let res = Some(TranscodeResult {
data: result,
width: ktx2_transcoder_get_r_width(transcoder),
height: ktx2_transcoder_get_r_height(transcoder),
levels: ktx2_transcoder_get_r_levels(transcoder),
layers: ktx2_transcoder_get_r_layers(transcoder),
faces: ktx2_transcoder_get_r_faces(transcoder),
is_srgb: ktx2_transcoder_get_r_is_srgb(transcoder),
target_format: ktx2_transcoder_get_r_target_format(transcoder),
basis_format: ktx2_transcoder_get_r_basis_format(transcoder),
});
ktx2_transcoder_delete(transcoder);
res
}
}
40 changes: 4 additions & 36 deletions crates/basisu_sys/src/native.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
#![expect(clippy::missing_safety_doc, reason = "TODO")]

use alloc::{vec, vec::Vec};

use crate::ChannelType;
use crate::SupportedTextureCompressionMethods;
use crate::TextureTranscodedFormat;
use crate::Transcoder;

pub use crate::transcoding::c_basisu_transcoder_init as basisu_transcoder_init;
pub use crate::transcoding::c_ktx2_transcoder_delete as ktx2_transcoder_delete;
pub use crate::transcoding::c_ktx2_transcoder_get_r_basis_format as ktx2_transcoder_get_r_basis_format;
pub use crate::transcoding::c_ktx2_transcoder_get_r_dst_buf_len as ktx2_transcoder_get_r_dst_buf_len;
pub use crate::transcoding::c_ktx2_transcoder_get_r_faces as ktx2_transcoder_get_r_faces;
pub use crate::transcoding::c_ktx2_transcoder_get_r_height as ktx2_transcoder_get_r_height;
pub use crate::transcoding::c_ktx2_transcoder_get_r_is_srgb as ktx2_transcoder_get_r_is_srgb;
Expand All @@ -17,30 +10,5 @@ pub use crate::transcoding::c_ktx2_transcoder_get_r_levels as ktx2_transcoder_ge
pub use crate::transcoding::c_ktx2_transcoder_get_r_target_format as ktx2_transcoder_get_r_target_format;
pub use crate::transcoding::c_ktx2_transcoder_get_r_width as ktx2_transcoder_get_r_width;
pub use crate::transcoding::c_ktx2_transcoder_new as ktx2_transcoder_new;

pub unsafe fn ktx2_transcoder_transcode_image(
transcoder: *mut Transcoder,
data: Vec<u8>,
supported_compressed_formats: SupportedTextureCompressionMethods,
channel_type_hint: ChannelType,
force_transcode_target: TextureTranscodedFormat,
) -> bool {
unsafe {
crate::transcoding::c_ktx2_transcoder_transcode_image(
transcoder,
data.as_ptr(),
u32::try_from(data.len()).unwrap(),
supported_compressed_formats,
channel_type_hint,
force_transcode_target,
)
}
}

pub unsafe fn ktx2_transcoder_get_r_dst_buf(transcoder: *mut Transcoder) -> Vec<u8> {
let ptr = unsafe { crate::transcoding::c_ktx2_transcoder_get_r_dst_buf(transcoder) };
let len = unsafe { crate::transcoding::c_ktx2_transcoder_get_r_dst_buf_len(transcoder) };
let mut ret = vec![0; len as usize];
unsafe { core::ptr::copy_nonoverlapping(ptr, ret.as_mut_ptr(), len as usize) };
ret
}
pub use crate::transcoding::c_ktx2_transcoder_transcode_image_get_info as ktx2_transcoder_transcode_image_get_info;
pub use crate::transcoding::c_ktx2_transcoder_transcode_image_write_buffer as ktx2_transcoder_transcode_image_write_buffer;
Loading
Loading