strat9_kernel/framebuffer/x86/
mod.rs1pub mod avx2;
2pub mod avx512;
3pub mod sse2;
4
5use crate::framebuffer::{generic, FramebufferOps};
6use raw_cpuid::CpuId;
7
8#[inline]
9fn kernel_can_use_extended_simd() -> bool {
10 #[cfg(target_os = "none")]
11 {
12 if !crate::arch::x86_64::cpuid::host_uses_xsave() {
13 return false;
14 }
15 let xcr0 = crate::arch::x86_64::xgetbv(0);
19 (xcr0 & 4) != 0 }
21
22 #[cfg(not(target_os = "none"))]
23 {
24 true
25 }
26}
27
28extern "C" {
29 pub fn strat9_fb_framebuffer_fill_avx2(dst: *mut u32, color: u32, count: usize);
32 pub fn strat9_fb_framebuffer_blit_avx2(dst: *mut u32, src: *const u32, count: usize);
33}
34
35unsafe fn fill_avx2_asm(dst: *mut u32, color: u32, count: usize) {
37 strat9_fb_framebuffer_fill_avx2(dst, color, count);
38}
39
40unsafe fn blit_avx2_asm(dst: *mut u32, src: *const u32, count: usize) {
42 strat9_fb_framebuffer_blit_avx2(dst, src, count);
43}
44
45pub fn detect_and_init_ops() -> FramebufferOps {
46 let cpuid = CpuId::new();
47
48 let has_avx512f = kernel_can_use_extended_simd()
49 && cpuid
50 .get_extended_feature_info()
51 .map_or(false, |info| info.has_avx512f());
52
53 let has_avx2 = kernel_can_use_extended_simd()
54 && cpuid
55 .get_extended_feature_info()
56 .map_or(false, |info| info.has_avx2());
57
58 let has_sse41 = cpuid
59 .get_feature_info()
60 .map_or(false, |info| info.has_sse41());
61
62 let has_ssse3 = cpuid
63 .get_feature_info()
64 .map_or(false, |info| info.has_ssse3());
65
66 let has_sse2 = cpuid
67 .get_feature_info()
68 .map_or(false, |info| info.has_sse2());
69
70 if has_avx512f {
71 FramebufferOps {
72 fill: avx512::fill_avx512,
73 blit: avx512::blit_avx512,
74 blend: avx512::blend_avx512,
75 convert: avx512::convert_bgr_to_argb_avx512,
76 }
77 } else if has_avx2 {
78 FramebufferOps {
79 fill: fill_avx2_asm, blit: blit_avx2_asm, blend: avx2::blend_avx2,
82 convert: avx2::convert_bgr_to_argb_avx2,
83 }
84 } else if has_sse41 || has_sse2 {
85 let convert: crate::framebuffer::FnConvert = if has_ssse3 {
87 sse2::convert_bgr_to_argb_sse2
88 } else {
89 generic::convert_bgr_to_argb_generic
90 };
91 FramebufferOps {
92 fill: sse2::fill_sse2,
93 blit: sse2::blit_sse2,
94 blend: sse2::blend_sse2,
95 convert,
96 }
97 } else {
98 FramebufferOps {
99 fill: generic::fill_generic,
100 blit: generic::blit_generic,
101 blend: generic::blend_generic,
102 convert: generic::convert_bgr_to_argb_generic,
103 }
104 }
105}