Skip to content

Commit a54ee83

Browse files
committed
Merge branch 'main' into rip-out-core-arch
2 parents ae1cfb6 + bcbc497 commit a54ee83

12 files changed

Lines changed: 446 additions & 35 deletions

File tree

CHANGELOG.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,25 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe
66
77
-->
88

9-
The latest published Fearless SIMD release is [0.4.0](#040-2026-02-13) which was released on 2026-02-13.
10-
You can find its changes [documented below](#040-2026-02-13).
9+
The latest published Fearless SIMD release is [0.4.1](#041-2026-05-16) which was released on 2026-05-16.
10+
You can find its changes [documented below](#041-2026-05-16).
1111

1212
## [Unreleased]
1313

1414
This release has an [MSRV][] of 1.88.
1515

16+
## [0.4.1][] (2026-05-16)
17+
18+
This release has an [MSRV][] of 1.88.
19+
20+
### Added
21+
22+
- The `interleave` and `deinterleave` methods on integer and floating-point SIMD vector types. ([#206][] by [@Shnatsel][])
23+
24+
### Fixed
25+
26+
- `Sse4_2` and `Avx2` now consistently use the x86-64-v2 and x86-64-v3 feature sets for detection, dispatch, and generated `target_feature` attributes. ([#208][] by [@Shnatsel][])
27+
1628
## [0.4.0][] (2026-02-13)
1729

1830
This release has an [MSRV][] of 1.88.
@@ -179,8 +191,11 @@ No changelog was kept for this release.
179191
[#181]: https://github.com/linebender/fearless_simd/pull/181
180192
[#185]: https://github.com/linebender/fearless_simd/pull/185
181193
[#188]: https://github.com/linebender/fearless_simd/pull/188
194+
[#206]: https://github.com/linebender/fearless_simd/pull/206
195+
[#208]: https://github.com/linebender/fearless_simd/pull/208
182196

183-
[Unreleased]: https://github.com/linebender/fearless_simd/compare/v0.4.0...HEAD
197+
[Unreleased]: https://github.com/linebender/fearless_simd/compare/v0.4.1...HEAD
198+
[0.4.1]: https://github.com/linebender/fearless_simd/compare/v0.4.0...v0.4.1
184199
[0.4.0]: https://github.com/linebender/fearless_simd/compare/v0.4.0...v0.3.0
185200
[0.3.0]: https://github.com/linebender/fearless_simd/compare/v0.3.0...v0.2.0
186201
[0.2.0]: https://github.com/linebender/fearless_simd/compare/e54304c66fc3e42d9604ddc7775b3345b589ce1a...v0.2.0

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fearless_simd/Cargo.toml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fearless_simd"
3-
version = "0.4.0"
3+
version = "0.4.1"
44
license.workspace = true
55
edition.workspace = true
66
repository.workspace = true
@@ -13,9 +13,16 @@ readme = "README.md"
1313

1414
[package.metadata.docs.rs]
1515
all-features = true
16-
# TODO: Get the right set of targets here. x86 linux, x86-64 linux, arm-macos, wasm
17-
# default-target = "x86_64-unknown-linux-gnu"
18-
# targets = []
16+
targets = [
17+
"x86_64-unknown-linux-gnu",
18+
"i686-unknown-linux-gnu",
19+
"aarch64-apple-darwin",
20+
"wasm32-unknown-unknown",
21+
]
22+
rustdoc-args = [
23+
"--cfg",
24+
'target_feature="simd128"',
25+
] # otherwise WASM docs only show the fallback level
1926

2027

2128
[features]

fearless_simd/examples/srgb.rs

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,68 @@
11
// Copyright 2024 the Fearless_SIMD Authors
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33

4-
#![expect(
5-
missing_docs,
6-
reason = "TODO: https://github.com/linebender/fearless_simd/issues/40"
7-
)]
4+
//! Converts a single RGBA pixel from linear RGB to sRGB.
5+
//!
6+
//! This example demonstrates the usual Fearless SIMD structure:
7+
//!
8+
//! - write the main computation as an `#[inline(always)]` function generic over
9+
//! [`Simd`];
10+
//! - use [`dispatch!`] at the non-SIMD boundary to run it with the best
11+
//! available target features;
12+
//! - drop down to [`kernel!`](fearless_simd::kernel) when a small part of the
13+
//! computation needs a target-specific intrinsic.
14+
//!
15+
//! The RGB channels are converted with portable SIMD operations. The alpha
16+
//! channel is copied unchanged, using an architecture-specific lane-copy
17+
//! intrinsic if one is available and a scalar fallback otherwise.
818
919
use fearless_simd::{Level, dispatch, f32x4, prelude::*};
1020

21+
#[cfg(target_arch = "aarch64")]
22+
use core::arch::aarch64::{float32x4_t, vcopyq_laneq_f32};
23+
#[cfg(target_arch = "x86")]
24+
use core::arch::x86::{__m128, _mm_blend_ps};
25+
#[cfg(target_arch = "x86_64")]
26+
use core::arch::x86_64::{__m128, _mm_blend_ps};
27+
28+
fearless_simd::kernel! {
29+
/// Copy the alpha lane on AArch64 using a NEON lane-copy intrinsic.
30+
#[inline]
31+
fn copy_alpha_neon(neon: Neon, a: float32x4_t, b: float32x4_t) -> float32x4_t {
32+
vcopyq_laneq_f32::<3, 3>(a, b)
33+
}
34+
}
35+
36+
fearless_simd::kernel! {
37+
/// Copy the alpha lane on x86 using the SSE4.2 token to enable SSE4.1 blend instructions.
38+
#[inline]
39+
fn copy_alpha_sse4_2(sse4_2: Sse4_2, a: __m128, b: __m128) -> __m128 {
40+
_mm_blend_ps::<8>(a, b)
41+
}
42+
}
43+
44+
/// Return `a` with its alpha channel replaced by `b`'s alpha channel.
45+
///
46+
/// This helper shows how portable SIMD code can opportunistically call
47+
/// target-specific kernels while still providing a fallback for every backend.
1148
#[inline(always)]
1249
fn copy_alpha<S: Simd>(a: f32x4<S>, b: f32x4<S>) -> f32x4<S> {
50+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
51+
if let Some(sse4_2) = a.simd.level().as_sse4_2() {
52+
return copy_alpha_sse4_2(sse4_2, a.into(), b.into()).simd_into(a.simd);
53+
}
54+
1355
#[cfg(target_arch = "aarch64")]
14-
if let Some(_neon) = a.simd.level().as_neon() {
15-
unsafe {
16-
return core::arch::aarch64::vcopyq_laneq_f32::<3, 3>(a.into(), b.into())
17-
.simd_into(a.simd);
18-
}
56+
if let Some(neon) = a.simd.level().as_neon() {
57+
return copy_alpha_neon(neon, a.into(), b.into()).simd_into(a.simd);
1958
}
59+
2060
let mut result = a;
2161
result[3] = b[3];
2262
result
2363
}
2464

65+
/// Approximate the linear-RGB to sRGB transfer curve for RGB, preserving alpha.
2566
#[inline(always)]
2667
fn to_srgb<S: Simd>(simd: S, rgba: [f32; 4]) -> [f32; 4] {
2768
let v: f32x4<S> = rgba.simd_into(simd);

fearless_simd/src/generated/simd_trait.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2991,6 +2991,7 @@ pub trait SimdBase<S: Simd>:
29912991
+ Sync
29922992
+ Send
29932993
+ 'static
2994+
+ Seal
29942995
+ Bytes
29952996
+ SimdFrom<Self::Element, S>
29962997
+ core::ops::Index<usize, Output = Self::Element>
@@ -3048,6 +3049,7 @@ pub trait SimdBase<S: Simd>:
30483049
#[doc = r" Functionality implemented by floating-point SIMD vectors."]
30493050
pub trait SimdFloat<S: Simd>:
30503051
SimdBase<S>
3052+
+ Seal
30513053
+ core::ops::Neg<Output = Self>
30523054
+ core::ops::Add<Output = Self>
30533055
+ core::ops::AddAssign
@@ -3142,6 +3144,7 @@ pub trait SimdFloat<S: Simd>:
31423144
#[doc = r" Functionality implemented by (signed and unsigned) integer SIMD vectors."]
31433145
pub trait SimdInt<S: Simd>:
31443146
SimdBase<S>
3147+
+ Seal
31453148
+ core::ops::Add<Output = Self>
31463149
+ core::ops::AddAssign
31473150
+ core::ops::Add<Self::Element, Output = Self>
@@ -3213,6 +3216,7 @@ pub trait SimdInt<S: Simd>:
32133216
#[doc = r" Functionality implemented by SIMD masks."]
32143217
pub trait SimdMask<S: Simd>:
32153218
SimdBase<S>
3219+
+ Seal
32163220
+ core::ops::BitAnd<Output = Self>
32173221
+ core::ops::BitAndAssign
32183222
+ core::ops::BitAnd<Self::Element, Output = Self>

0 commit comments

Comments
 (0)