use crate::ThreadingPolicy;
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};
use crate::image_store::ImageStore;
#[cfg(all(target_arch = "aarch64", feature = "neon"))]
use crate::neon::*;
use crate::plan::{HorizontalFiltering, VerticalFiltering};
#[cfg(all(any(target_arch = "x86_64", target_arch = "x86"), feature = "sse"))]
use crate::sse::*;
use std::sync::Arc;
impl HorizontalFilterPass<f32, f32, 2> for ImageStore<'_, f32, 2> {
fn horizontal_plan(
filter_weights: FilterWeights<f32>,
threading_policy: ThreadingPolicy,
_: ConvolutionOptions,
) -> Arc<dyn RowFilter<f32, 2> + Send + Sync> {
let _dispatcher_4_rows: Option<
fn(&[f32], usize, &mut [f32], usize, &FilterWeights<f32>, u32),
> = Some(convolve_horizontal_rgba_4_row_f32::<2>);
let _dispatcher_row: fn(&[f32], &mut [f32], &FilterWeights<f32>, u32) =
convolve_horizontal_native_row_f32::<2>;
Arc::new(HorizontalFiltering {
filter_weights,
filter_4_rows: _dispatcher_4_rows,
filter_row: _dispatcher_row,
threading_policy,
})
}
}
impl HorizontalFilterPass<f32, f64, 2> for ImageStore<'_, f32, 2> {
fn horizontal_plan(
filter_weights: FilterWeights<f64>,
threading_policy: ThreadingPolicy,
_: ConvolutionOptions,
) -> Arc<dyn RowFilter<f32, 2> + Send + Sync> {
let _dispatcher_4_rows: Option<
fn(&[f32], usize, &mut [f32], usize, &FilterWeights<f64>, u32),
> = Some(convolve_horizontal_4_row_f32_f64::<2>);
let _dispatcher_row: fn(&[f32], &mut [f32], &FilterWeights<f64>, u32) =
convolve_horizontal_native_row_f32_f64::<2>;
Arc::new(HorizontalFiltering {
filter_weights,
filter_4_rows: _dispatcher_4_rows,
filter_row: _dispatcher_row,
threading_policy,
})
}
}
impl VerticalConvolutionPass<f32, f32, 2> for ImageStore<'_, f32, 2> {
fn vertical_plan(
filter_weights: FilterWeights<f32>,
threading_policy: ThreadingPolicy,
_: ConvolutionOptions,
) -> Arc<dyn ColumnFilter<f32, 2> + 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, 2> for ImageStore<'_, f32, 2> {
fn vertical_plan(
filter_weights: FilterWeights<f64>,
threading_policy: ThreadingPolicy,
_: ConvolutionOptions,
) -> Arc<dyn ColumnFilter<f32, 2> + 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;
}
#[cfg(all(target_arch = "x86_64", feature = "avx"))]
{
if std::arch::is_x86_feature_detected!("avx2") {
if std::arch::is_x86_feature_detected!("fma") {
use crate::avx2::convolve_vertical_avx_row_f32_f64_fma;
_dispatcher = convolve_vertical_avx_row_f32_f64_fma;
} else {
use crate::avx2::convolve_vertical_avx_row_f32_f64_default;
_dispatcher = convolve_vertical_avx_row_f32_f64_default;
}
}
}
Arc::new(VerticalFiltering {
filter_weights,
filter_row: _dispatcher,
threading_policy,
})
}
}