use crate::convolution::{
ColumnFilter, ConvolutionOptions, HorizontalFilterPass, RowFilter, VerticalConvolutionPass,
};
use crate::convolve_naive_f32::{
convolve_horizontal_4_row_f32_f64, convolve_horizontal_native_row_f32,
convolve_horizontal_native_row_f32_f64, convolve_horizontal_rgba_4_row_f32,
};
use crate::factory::rgb_f32::{
convolve_vertical_rgb_native_row_f32, convolve_vertical_rgb_native_row_f64,
};
use crate::filter_weights::{FilterBounds, FilterWeights};
#[cfg(all(target_arch = "aarch64", feature = "neon",))]
use crate::neon::{
convolve_horizontal_plane_neon_row_one, convolve_horizontal_plane_neon_rows_4,
convolve_vertical_rgb_neon_row_f32,
};
use crate::plan::{HorizontalFiltering, VerticalFiltering};
#[cfg(all(any(target_arch = "x86_64", target_arch = "x86"), feature = "sse"))]
use crate::sse::{
convolve_horizontal_plane_sse_row_one, convolve_horizontal_plane_sse_rows_4,
convolve_vertical_rgb_sse_row_f32,
};
use crate::{ImageStore, ThreadingPolicy};
use std::sync::Arc;
impl HorizontalFilterPass<f32, f32, 1> for ImageStore<'_, f32, 1> {
fn horizontal_plan(
filter_weights: FilterWeights<f32>,
threading_policy: ThreadingPolicy,
_: ConvolutionOptions,
) -> Arc<dyn RowFilter<f32, 1> + Send + Sync> {
let mut _dispatcher_4_rows: Option<
fn(&[f32], usize, &mut [f32], usize, &FilterWeights<f32>, u32),
> = Some(convolve_horizontal_rgba_4_row_f32::<1>);
let mut _dispatcher_row: fn(&[f32], &mut [f32], &FilterWeights<f32>, u32) =
convolve_horizontal_native_row_f32::<1>;
#[cfg(all(target_arch = "aarch64", feature = "neon"))]
{
_dispatcher_4_rows = Some(convolve_horizontal_plane_neon_rows_4);
_dispatcher_row = convolve_horizontal_plane_neon_row_one;
}
#[cfg(all(any(target_arch = "x86_64", target_arch = "x86"), feature = "sse"))]
{
if std::arch::is_x86_feature_detected!("sse4.1") {
_dispatcher_4_rows = Some(convolve_horizontal_plane_sse_rows_4);
_dispatcher_row = convolve_horizontal_plane_sse_row_one;
}
}
#[cfg(all(target_arch = "x86_64", feature = "avx"))]
{
use crate::avx2::{
convolve_horizontal_plane_avx_row_one_f32_default,
convolve_horizontal_plane_avx_row_one_f32_fma,
convolve_horizontal_plane_avx_rows_4_f32_default,
convolve_horizontal_plane_avx_rows_4_f32_fma,
};
let has_fma = std::arch::is_x86_feature_detected!("fma");
if std::arch::is_x86_feature_detected!("avx2") {
_dispatcher_4_rows = Some(convolve_horizontal_plane_avx_rows_4_f32_default);
_dispatcher_row = convolve_horizontal_plane_avx_row_one_f32_default;
if has_fma {
_dispatcher_4_rows = Some(convolve_horizontal_plane_avx_rows_4_f32_fma);
_dispatcher_row = convolve_horizontal_plane_avx_row_one_f32_fma;
}
}
}
Arc::new(HorizontalFiltering {
filter_weights,
filter_4_rows: _dispatcher_4_rows,
filter_row: _dispatcher_row,
threading_policy,
})
}
}
impl HorizontalFilterPass<f32, f64, 1> for ImageStore<'_, f32, 1> {
fn horizontal_plan(
filter_weights: FilterWeights<f64>,
threading_policy: ThreadingPolicy,
_: ConvolutionOptions,
) -> Arc<dyn RowFilter<f32, 1> + Send + Sync> {
let mut _dispatcher_4_rows: Option<
fn(&[f32], usize, &mut [f32], usize, &FilterWeights<f64>, u32),
> = Some(convolve_horizontal_4_row_f32_f64::<1>);
let mut _dispatcher_row: fn(&[f32], &mut [f32], &FilterWeights<f64>, u32) =
convolve_horizontal_native_row_f32_f64::<1>;
#[cfg(all(target_arch = "aarch64", feature = "neon"))]
{
use crate::neon::{
convolve_horizontal_plane_neon_row_one_f32_f64,
convolve_horizontal_plane_neon_rows_4_f32_f64,
};
_dispatcher_4_rows = Some(convolve_horizontal_plane_neon_rows_4_f32_f64);
_dispatcher_row = convolve_horizontal_plane_neon_row_one_f32_f64;
}
#[cfg(all(target_arch = "x86_64", feature = "avx"))]
{
if std::arch::is_x86_feature_detected!("avx2") {
use crate::avx2::{
convolve_hor_plane_avx_row_one_f32_f64_default,
convolve_hor_plane_avx_row_one_f32_f64_fma,
convolve_hor_plane_avx_rows_4_f32_f64_default,
convolve_hor_plane_avx_rows_4_f32_f64_fma,
};
_dispatcher_4_rows = Some(convolve_hor_plane_avx_rows_4_f32_f64_default);
_dispatcher_row = convolve_hor_plane_avx_row_one_f32_f64_default;
if std::arch::is_x86_feature_detected!("fma") {
_dispatcher_4_rows = Some(convolve_hor_plane_avx_rows_4_f32_f64_fma);
_dispatcher_row = convolve_hor_plane_avx_row_one_f32_f64_fma;
}
}
}
Arc::new(HorizontalFiltering {
filter_weights,
filter_4_rows: _dispatcher_4_rows,
filter_row: _dispatcher_row,
threading_policy,
})
}
}
impl VerticalConvolutionPass<f32, f32, 1> for ImageStore<'_, f32, 1> {
fn vertical_plan(
filter_weights: FilterWeights<f32>,
threading_policy: ThreadingPolicy,
_: ConvolutionOptions,
) -> Arc<dyn ColumnFilter<f32, 1> + Send + Sync> {
#[allow(clippy::type_complexity)]
let mut _dispatcher: fn(
usize,
&FilterBounds,
&[f32],
&mut [f32],
usize,
&[f32],
u32,
) = convolve_vertical_rgb_native_row_f32;
#[cfg(all(target_arch = "aarch64", feature = "neon"))]
{
_dispatcher = convolve_vertical_rgb_neon_row_f32;
}
#[cfg(all(any(target_arch = "x86_64", target_arch = "x86"), feature = "sse"))]
{
if std::arch::is_x86_feature_detected!("sse4.1") {
_dispatcher = convolve_vertical_rgb_sse_row_f32;
}
}
#[cfg(all(target_arch = "x86_64", feature = "avx"))]
{
let has_fma = std::arch::is_x86_feature_detected!("fma");
if std::arch::is_x86_feature_detected!("avx2") {
use crate::avx2::convolve_vertical_avx_row_default_f32;
_dispatcher = convolve_vertical_avx_row_default_f32;
if has_fma {
use crate::avx2::convolve_vertical_avx_row_fma_f32;
_dispatcher = convolve_vertical_avx_row_fma_f32;
}
}
}
Arc::new(VerticalFiltering {
filter_weights,
filter_row: _dispatcher,
threading_policy,
})
}
}
impl VerticalConvolutionPass<f32, f64, 1> for ImageStore<'_, f32, 1> {
fn vertical_plan(
filter_weights: FilterWeights<f64>,
threading_policy: ThreadingPolicy,
_: ConvolutionOptions,
) -> Arc<dyn ColumnFilter<f32, 1> + Send + Sync> {
#[allow(clippy::type_complexity)]
let mut _dispatcher: fn(
usize,
&FilterBounds,
&[f32],
&mut [f32],
usize,
&[f64],
u32,
) = convolve_vertical_rgb_native_row_f64;
#[cfg(all(target_arch = "aarch64", feature = "neon"))]
{
use crate::neon::convolve_vertical_neon_row_f32_f64;
_dispatcher = convolve_vertical_neon_row_f32_f64;
}
Arc::new(VerticalFiltering {
filter_weights,
filter_row: _dispatcher,
threading_policy,
})
}
}