#[cfg(all(target_arch = "x86_64", feature = "avx2"))]
mod avx2;
mod rust;
#[cfg(test)]
mod tests;
use std::{mem::size_of, num::NonZeroUsize};
use crate::util::Pixel;
pub type SatdFn = unsafe fn(
src: *const u8,
src_pitch: NonZeroUsize,
ref_: *const u8,
ref_pitch: NonZeroUsize,
) -> u64;
#[must_use]
#[inline]
pub fn select_satd<T: Pixel>(width: NonZeroUsize, height: NonZeroUsize) -> SatdFn {
#[cfg(all(target_arch = "x86_64", feature = "avx2"))]
if crate::util::has_avx2() {
match (size_of::<T>(), width.get(), height.get()) {
(1, 4, 4) => return avx2::get_satd_u8::<4, 4>,
(1, 8, 4) => return avx2::get_satd_u8::<8, 4>,
(1, 8, 8) => return avx2::get_satd_u8::<8, 8>,
(1, 16, 8) => return avx2::get_satd_u8::<16, 8>,
(1, 16, 16) => return avx2::get_satd_u8::<16, 16>,
(1, 32, 16) => return avx2::get_satd_u8::<32, 16>,
(1, 32, 32) => return avx2::get_satd_u8::<32, 32>,
(1, 64, 32) => return avx2::get_satd_u8::<64, 32>,
(1, 64, 64) => return avx2::get_satd_u8::<64, 64>,
(1, 128, 64) => return avx2::get_satd_u8::<128, 64>,
(1, 128, 128) => return avx2::get_satd_u8::<128, 128>,
(2, 4, 4) => return avx2::get_satd_u16::<4, 4>,
(2, 8, 4) => return avx2::get_satd_u16::<8, 4>,
(2, 8, 8) => return avx2::get_satd_u16::<8, 8>,
(2, 16, 8) => return avx2::get_satd_u16::<16, 8>,
(2, 16, 16) => return avx2::get_satd_u16::<16, 16>,
(2, 32, 16) => return avx2::get_satd_u16::<32, 16>,
(2, 32, 32) => return avx2::get_satd_u16::<32, 32>,
(2, 64, 32) => return avx2::get_satd_u16::<64, 32>,
(2, 64, 64) => return avx2::get_satd_u16::<64, 64>,
(2, 128, 64) => return avx2::get_satd_u16::<128, 64>,
(2, 128, 128) => return avx2::get_satd_u16::<128, 128>,
_ => {}
};
}
match (size_of::<T>(), width.get(), height.get()) {
(1, 4, 4) => rust::get_satd_u8::<4, 4>,
(1, 8, 4) => rust::get_satd_u8::<8, 4>,
(1, 8, 8) => rust::get_satd_u8::<8, 8>,
(1, 16, 8) => rust::get_satd_u8::<16, 8>,
(1, 16, 16) => rust::get_satd_u8::<16, 16>,
(1, 32, 16) => rust::get_satd_u8::<32, 16>,
(1, 32, 32) => rust::get_satd_u8::<32, 32>,
(1, 64, 32) => rust::get_satd_u8::<64, 32>,
(1, 64, 64) => rust::get_satd_u8::<64, 64>,
(1, 128, 64) => rust::get_satd_u8::<128, 64>,
(1, 128, 128) => rust::get_satd_u8::<128, 128>,
(2, 4, 4) => rust::get_satd_u16::<4, 4>,
(2, 8, 4) => rust::get_satd_u16::<8, 4>,
(2, 8, 8) => rust::get_satd_u16::<8, 8>,
(2, 16, 8) => rust::get_satd_u16::<16, 8>,
(2, 16, 16) => rust::get_satd_u16::<16, 16>,
(2, 32, 16) => rust::get_satd_u16::<32, 16>,
(2, 32, 32) => rust::get_satd_u16::<32, 32>,
(2, 64, 32) => rust::get_satd_u16::<64, 32>,
(2, 64, 64) => rust::get_satd_u16::<64, 64>,
(2, 128, 64) => rust::get_satd_u16::<128, 64>,
(2, 128, 128) => rust::get_satd_u16::<128, 128>,
_ => panic!("unsupported block size for SATD: {}x{}", width, height),
}
}