mirror of
https://github.com/Cykooz/fast_image_resize.git
synced 2026-10-07 17:01:09 +00:00
Added using cpufeatures crate for no_std environment.
This commit is contained in:
Generated
+1
@@ -575,6 +575,7 @@ version = "5.5.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"criterion",
|
||||
"document-features",
|
||||
"fast_image_resize",
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ document-features = { version = "0.2.12", optional = true }
|
||||
image = { version = "0.25.6", optional = true, default-features = false }
|
||||
bytemuck = { version = "1.24", optional = true }
|
||||
rayon = { version = "1.11", optional = true }
|
||||
|
||||
cpufeatures = { version = "0.2.17", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
@@ -38,7 +38,7 @@ std = ["thiserror/std", "num-traits/std", "dep:document-features"]
|
||||
## To prevent conflicts with the `std` feature it is not used for
|
||||
## conditional compilation. It just installs additional dependencies
|
||||
## or activates some features of existing dependencies.
|
||||
no_std = ["num-traits/libm"]
|
||||
no_std = ["num-traits/libm", "dep:cpufeatures"]
|
||||
## Enable this feature to implement traits [IntoImageView](crate::IntoImageView) and
|
||||
## [IntoImageViewMut](crate::IntoImageViewMut) for the
|
||||
## [DynamicImage](https://docs.rs/image/latest/image/enum.DynamicImage.html)
|
||||
|
||||
+4
-9
@@ -2,15 +2,10 @@
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "std")] {
|
||||
pub use std::boxed::Box;
|
||||
pub use std::{vec, vec::Vec};
|
||||
pub use std::borrow::ToOwned;
|
||||
mod std_impl;
|
||||
pub use std_impl::*;
|
||||
} else {
|
||||
pub use alloc::boxed::Box;
|
||||
pub use alloc::{vec, vec::Vec};
|
||||
pub use alloc::borrow::ToOwned;
|
||||
|
||||
// `no_std` feature must be enabled
|
||||
pub use num_traits::Float;
|
||||
mod no_std_impl;
|
||||
pub use no_std_impl::*;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
pub use alloc::borrow::ToOwned;
|
||||
pub use alloc::boxed::Box;
|
||||
pub use alloc::vec;
|
||||
pub use alloc::vec::Vec;
|
||||
|
||||
// `no_std` feature must be enabled
|
||||
pub use num_traits::Float;
|
||||
|
||||
// `no_std` feature must be enabled
|
||||
cpufeatures::new!(cpuid_sse41, "sse4.1");
|
||||
cpufeatures::new!(cpuid_avx2, "avx2");
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn has_avx2() -> bool {
|
||||
cpuid_avx2::get()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn has_sse41() -> bool {
|
||||
cpuid_sse41::get()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub fn has_neon() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn has_simd128() -> bool {
|
||||
true
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
pub use std::borrow::ToOwned;
|
||||
pub use std::boxed::Box;
|
||||
pub use std::vec;
|
||||
pub use std::vec::Vec;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn has_avx2() -> bool {
|
||||
std::is_x86_feature_detected!("avx2")
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn has_sse41() -> bool {
|
||||
std::is_x86_feature_detected!("sse4.1")
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub fn has_neon() -> bool {
|
||||
std::arch::is_aarch64_feature_detected!("neon")
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn has_simd128() -> bool {
|
||||
true
|
||||
}
|
||||
+10
-48
@@ -1,3 +1,5 @@
|
||||
use crate::compat::*;
|
||||
|
||||
/// SIMD extension of CPU.
|
||||
/// Specific variants depend on target architecture.
|
||||
/// Look at source code to see all available variants.
|
||||
@@ -23,63 +25,24 @@ impl CpuExtensions {
|
||||
pub fn is_supported(&self) -> bool {
|
||||
match self {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
Self::Avx2 => Self::has_avx2(),
|
||||
Self::Avx2 => has_avx2(),
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
Self::Sse4_1 => Self::has_sse41(),
|
||||
Self::Sse4_1 => has_sse41(),
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
// FIXME: Not sure how, I don't know ARM assembly. AFAIK, all ARM compliant
|
||||
// processors must implement NEON
|
||||
Self::Neon => true,
|
||||
Self::Neon => has_neon(),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Self::Simd128 => true,
|
||||
Self::Simd128 => has_simd128(),
|
||||
Self::None => true,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#[inline]
|
||||
fn has_avx2() -> bool {
|
||||
use core::arch::x86_64::{__cpuid, __cpuid_count, _xgetbv};
|
||||
|
||||
unsafe {
|
||||
let cpuid1 = __cpuid(1);
|
||||
|
||||
if (cpuid1.ecx & (1 << 27)) == 0 || (cpuid1.ecx & (1 << 28)) == 0 {
|
||||
// OSXSAVE + AVX
|
||||
return false;
|
||||
}
|
||||
|
||||
let xcr0 = _xgetbv(0);
|
||||
if (xcr0 & 0b110) != 0b110 {
|
||||
// XCR0: XMM (bit 1) and YMM (bit 2) enabled
|
||||
return false;
|
||||
}
|
||||
|
||||
// CPUID leaf 7 subleaf 0: AVX2
|
||||
let cpuid7 = __cpuid_count(7, 0);
|
||||
(cpuid7.ebx & (1 << 5)) != 0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#[inline]
|
||||
fn has_sse41() -> bool {
|
||||
use core::arch::x86_64::__cpuid;
|
||||
|
||||
// CPUID leaf 1: feature bits
|
||||
let res = unsafe { __cpuid(1) };
|
||||
|
||||
// ECX bit 19 = SSE4.1
|
||||
(res.ecx & (1 << 19)) != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CpuExtensions {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn default() -> Self {
|
||||
if Self::has_avx2() {
|
||||
if has_avx2() {
|
||||
Self::Avx2
|
||||
} else if Self::has_sse41() {
|
||||
} else if has_sse41() {
|
||||
Self::Sse4_1
|
||||
} else {
|
||||
Self::None
|
||||
@@ -88,12 +51,11 @@ impl Default for CpuExtensions {
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn default() -> Self {
|
||||
// FIXME: Maybe we detect?
|
||||
Self::Neon
|
||||
has_neon()
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fn default() -> Self {
|
||||
Self::Simd128
|
||||
has_simd128()
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
|
||||
Reference in New Issue
Block a user