strat9_kernel/framebuffer/x86/
sse2.rs1use core::arch::x86_64::*;
2
3#[inline]
4unsafe fn load_u32_unaligned(src: *const u8) -> i32 {
5 core::ptr::read_unaligned(src as *const u32) as i32
6}
7
8#[target_feature(enable = "sse2")]
9pub unsafe fn fill_sse2(dst: *mut u32, color: u32, count: usize) {
10 let color_vec = _mm_set1_epi32(color as i32);
11 let mut i = 0;
12
13 while i + 4 <= count {
14 _mm_storeu_si128(dst.add(i) as *mut __m128i, color_vec);
15 i += 4;
16 }
17
18 while i < count {
19 *dst.add(i) = color;
20 i += 1;
21 }
22}
23
24#[target_feature(enable = "sse2")]
25pub unsafe fn blit_sse2(dst: *mut u32, src: *const u32, count: usize) {
26 let mut i = 0;
27
28 while i + 4 <= count {
29 let src_vec = _mm_loadu_si128(src.add(i) as *const __m128i);
30 _mm_storeu_si128(dst.add(i) as *mut __m128i, src_vec);
31 i += 4;
32 }
33
34 while i < count {
35 *dst.add(i) = *src.add(i);
36 i += 1;
37 }
38}
39
40#[target_feature(enable = "sse2")]
43pub unsafe fn blend_sse2(dst: *mut u32, src: *const u32, alpha: u8, count: usize) {
44 let alpha_u16 = alpha as u16;
46 let inv_alpha = 255 - alpha_u16;
47
48 let alpha_vec = _mm_set1_epi16(alpha_u16 as i16);
49 let inv_alpha_vec = _mm_set1_epi16(inv_alpha as i16);
50 let zero = _mm_setzero_si128();
51 let ones = _mm_set1_epi16(1);
52
53 let mut i = 0;
54 while i + 4 <= count {
55 let d = _mm_loadu_si128(dst.add(i) as *const __m128i);
56 let s = _mm_loadu_si128(src.add(i) as *const __m128i);
57
58 let d_lo = _mm_unpacklo_epi8(d, zero);
59 let d_hi = _mm_unpackhi_epi8(d, zero);
60 let s_lo = _mm_unpacklo_epi8(s, zero);
61 let s_hi = _mm_unpackhi_epi8(s, zero);
62
63 let res_lo_s = _mm_mullo_epi16(s_lo, alpha_vec);
64 let res_lo_d = _mm_mullo_epi16(d_lo, inv_alpha_vec);
65 let res_lo = _mm_add_epi16(res_lo_s, res_lo_d);
66 let lo_div = _mm_srli_epi16(res_lo, 8);
68 let lo_corr = _mm_add_epi16(res_lo, _mm_add_epi16(lo_div, ones));
69 let res_lo_final = _mm_srli_epi16(lo_corr, 8);
70
71 let res_hi_s = _mm_mullo_epi16(s_hi, alpha_vec);
72 let res_hi_d = _mm_mullo_epi16(d_hi, inv_alpha_vec);
73 let res_hi = _mm_add_epi16(res_hi_s, res_hi_d);
74 let hi_div = _mm_srli_epi16(res_hi, 8);
75 let hi_corr = _mm_add_epi16(res_hi, _mm_add_epi16(hi_div, ones));
76 let res_hi_final = _mm_srli_epi16(hi_corr, 8);
77
78 let res = _mm_packus_epi16(res_lo_final, res_hi_final);
79 _mm_storeu_si128(dst.add(i) as *mut __m128i, res);
80 i += 4;
81 }
82
83 if i < count {
85 crate::framebuffer::generic::blend_generic(dst.add(i), src.add(i), alpha, count - i);
86 }
87}
88
89#[target_feature(enable = "sse2")]
90pub unsafe fn convert_bgr_to_argb_sse2(dst: *mut u32, src: *const u8, count: usize) {
91 convert_bgr_to_argb_ssse3(dst, src, count);
92}
93
94#[target_feature(enable = "ssse3")]
96unsafe fn convert_bgr_to_argb_ssse3(dst: *mut u32, src: *const u8, count: usize) {
97 #[rustfmt::skip]
102 let shuffle_mask = _mm_set_epi8(
103 -1, 11, 10, 9, -1, 8, 7, 6, -1, 5, 4, 3, -1, 2, 1, 0, );
108 let alpha_mask = _mm_set1_epi32(0xFF000000_u32 as i32);
110
111 let mut i = 0;
112 while i + 4 <= count {
114 let lo8 = _mm_loadl_epi64(src.add(i * 3) as *const __m128i);
116 let hi4 = _mm_cvtsi32_si128(load_u32_unaligned(src.add(i * 3 + 8)));
117 let raw = _mm_unpacklo_epi64(lo8, hi4);
118 let shuffled = _mm_shuffle_epi8(raw, shuffle_mask);
119 let result = _mm_or_si128(shuffled, alpha_mask);
120 _mm_storeu_si128(dst.add(i) as *mut __m128i, result);
121 i += 4;
122 }
123
124 if i < count {
126 crate::framebuffer::generic::convert_bgr_to_argb_generic(
127 dst.add(i),
128 src.add(i * 3),
129 count - i,
130 );
131 }
132}