From 3a617f8923d8fd3bf01cc2fc9e5999ceec2dbeaf Mon Sep 17 00:00:00 2001 From: Nicole L Date: Mon, 24 Jul 2023 13:46:26 -0700 Subject: [PATCH] `fn wiener_{c => rust}`: Deduplicate w/ generics (#334) --- include/common/bitdepth.rs | 10 +++ src/looprestoration.rs | 107 +++++++++++++++++++++++++++++++++ src/looprestoration_tmpl_16.rs | 95 +---------------------------- src/looprestoration_tmpl_8.rs | 92 +--------------------------- 4 files changed, 121 insertions(+), 183 deletions(-) diff --git a/include/common/bitdepth.rs b/include/common/bitdepth.rs index 9bd684804..0a0f07f76 100644 --- a/include/common/bitdepth.rs +++ b/include/common/bitdepth.rs @@ -96,6 +96,8 @@ pub trait BitDepth: Clone + Copy { fn new(bitdepth_max: Self::BitDepthMax) -> Self; + fn from_c(bitdepth_max: libc::c_int) -> Self; + fn pixel_copy(dest: &mut [Self::Pixel], src: &[Self::Pixel], n: usize) { dest[..n].copy_from_slice(&src[..n]); } @@ -145,6 +147,10 @@ impl BitDepth for BitDepth8 { Self { bitdepth_max } } + fn from_c(_bitdepth_max: libc::c_int) -> Self { + Self::new(()) + } + fn display(pixel: Self::Pixel) -> Self::DisplayPixel { DisplayPixel8(pixel) } @@ -189,6 +195,10 @@ impl BitDepth for BitDepth16 { Self { bitdepth_max } } + fn from_c(bitdepth_max: libc::c_int) -> Self { + Self::new(bitdepth_max as Self::BitDepthMax) + } + fn display(pixel: Self::Pixel) -> Self::DisplayPixel { DisplayPixel16(pixel) } diff --git a/src/looprestoration.rs b/src/looprestoration.rs index ba8f2522c..6e6463f9c 100644 --- a/src/looprestoration.rs +++ b/src/looprestoration.rs @@ -1,6 +1,9 @@ +use crate::include::common::bitdepth::AsPrimitive; use crate::include::common::bitdepth::BitDepth; +use crate::include::common::intops::iclip; use crate::include::stddef::ptrdiff_t; use crate::include::stdint::int16_t; +use crate::include::stdint::uint16_t; use crate::include::stdint::uint32_t; use crate::src::align::Align16; @@ -48,6 +51,7 @@ pub struct Dav1dLoopRestorationDSPContext { pub sgr: [looprestorationfilter_fn; 3], } +#[cfg(feature = "asm")] macro_rules! decl_looprestorationfilter_fns { ( $( fn $name:ident, )* ) => { extern "C" { @@ -292,3 +296,106 @@ pub(crate) unsafe fn padding( } }; } + +// TODO(randompoison): Temporarily public until init logic is deduplicated. +pub(crate) unsafe extern "C" fn wiener_c_erased( + mut p: *mut libc::c_void, + stride: ptrdiff_t, + left: *const libc::c_void, + mut lpf: *const libc::c_void, + w: libc::c_int, + h: libc::c_int, + params: *const LooprestorationParams, + edges: LrEdgeFlags, + bitdepth_max: libc::c_int, +) { + let bd = BD::from_c(bitdepth_max); + wiener_rust::( + p.cast(), + stride, + left.cast(), + lpf.cast(), + w, + h, + params, + edges, + bd, + ) +} + +unsafe fn wiener_rust( + mut p: *mut BD::Pixel, + stride: ptrdiff_t, + left: *const [BD::Pixel; 4], + mut lpf: *const BD::Pixel, + w: libc::c_int, + h: libc::c_int, + params: *const LooprestorationParams, + edges: LrEdgeFlags, + bd: BD, +) { + let mut tmp: [BD::Pixel; 27300] = [0.as_(); 27300]; + let mut tmp_ptr: *mut BD::Pixel = tmp.as_mut_ptr(); + + padding::(&mut tmp, p, stride, left, lpf, w, h, edges); + + let mut hor: [uint16_t; 27300] = [0; 27300]; + let mut hor_ptr: *mut uint16_t = hor.as_mut_ptr(); + let filter: *const [int16_t; 8] = ((*params).filter.0).as_ptr(); + let bitdepth = bd.bitdepth().as_::(); + let round_bits_h = 3 as libc::c_int + (bitdepth == 12) as libc::c_int * 2; + let rounding_off_h = (1 as libc::c_int) << round_bits_h - 1; + let clip_limit = (1 as libc::c_int) << bitdepth + 1 + 7 - round_bits_h; + let mut j = 0; + while j < h + 6 { + let mut i = 0; + while i < w { + let mut sum = (1 as libc::c_int) << bitdepth + 6; + + if BD::BITDEPTH == 8 { + sum += (*tmp_ptr.offset((i + 3) as isize)).as_::() * 128; + } + + let mut k = 0; + while k < 7 { + sum += (*tmp_ptr.offset((i + k) as isize)).as_::() + * (*filter.offset(0))[k as usize] as libc::c_int; + k += 1; + } + *hor_ptr.offset(i as isize) = iclip( + sum + rounding_off_h >> round_bits_h, + 0 as libc::c_int, + clip_limit - 1, + ) as uint16_t; + i += 1; + } + tmp_ptr = tmp_ptr.offset(390); + hor_ptr = hor_ptr.offset(390); + j += 1; + } + let round_bits_v = 11 as libc::c_int - (bitdepth == 12) as libc::c_int * 2; + let rounding_off_v = (1 as libc::c_int) << round_bits_v - 1; + let round_offset = (1 as libc::c_int) << bitdepth + (round_bits_v - 1); + let mut j_0 = 0; + while j_0 < h { + let mut i_0 = 0; + while i_0 < w { + let mut sum_0 = -round_offset; + let mut k_0 = 0; + while k_0 < 7 { + sum_0 += hor[((j_0 + k_0) * 390 + i_0) as usize] as libc::c_int + * (*filter.offset(1))[k_0 as usize] as libc::c_int; + k_0 += 1; + } + *p.offset(j_0 as isize * BD::pxstride(stride as usize) as isize + i_0 as isize) = + iclip( + sum_0 + rounding_off_v >> round_bits_v, + 0 as libc::c_int, + bd.bitdepth_max().as_(), + ) + .as_(); + i_0 += 1; + } + j_0 += 1; + } +} diff --git a/src/looprestoration_tmpl_16.rs b/src/looprestoration_tmpl_16.rs index 07ca5045d..358ef8263 100644 --- a/src/looprestoration_tmpl_16.rs +++ b/src/looprestoration_tmpl_16.rs @@ -140,6 +140,7 @@ use crate::include::common::intops::iclip; use crate::include::common::intops::imax; use crate::include::common::intops::umin; use crate::src::looprestoration::padding; +use crate::src::looprestoration::wiener_c_erased; use crate::src::looprestoration::Dav1dLoopRestorationDSPContext; #[inline] @@ -150,98 +151,6 @@ unsafe extern "C" fn PXSTRIDE(x: ptrdiff_t) -> ptrdiff_t { return x >> 1; } -unsafe extern "C" fn wiener_c( - mut p: *mut libc::c_void, - stride: ptrdiff_t, - left: *const libc::c_void, - mut lpf: *const libc::c_void, - w: libc::c_int, - h: libc::c_int, - params: *const LooprestorationParams, - edges: LrEdgeFlags, - bitdepth_max: libc::c_int, -) { - wiener_rust( - p.cast(), - stride, - left.cast(), - lpf.cast(), - w, - h, - params, - edges, - bitdepth_max, - ) -} - -// TODO(randompoison): Temporarily public until we can move this to `looprestoration.rs`. -pub(crate) unsafe extern "C" fn wiener_rust( - mut p: *mut pixel, - stride: ptrdiff_t, - left: *const [pixel; 4], - mut lpf: *const pixel, - w: libc::c_int, - h: libc::c_int, - params: *const LooprestorationParams, - edges: LrEdgeFlags, - bitdepth_max: libc::c_int, -) { - let mut tmp: [pixel; 27300] = [0; 27300]; - let mut tmp_ptr: *mut pixel = tmp.as_mut_ptr(); - padding::(&mut tmp, p, stride, left, lpf, w, h, edges); - let mut hor: [uint16_t; 27300] = [0; 27300]; - let mut hor_ptr: *mut uint16_t = hor.as_mut_ptr(); - let filter: *const [int16_t; 8] = ((*params).filter.0).as_ptr(); - let bitdepth = 32 - clz(bitdepth_max as libc::c_uint); - let round_bits_h = 3 as libc::c_int + (bitdepth == 12) as libc::c_int * 2; - let rounding_off_h = (1 as libc::c_int) << round_bits_h - 1; - let clip_limit = (1 as libc::c_int) << bitdepth + 1 + 7 - round_bits_h; - let mut j = 0; - while j < h + 6 { - let mut i = 0; - while i < w { - let mut sum = (1 as libc::c_int) << bitdepth + 6; - let mut k = 0; - while k < 7 { - sum += *tmp_ptr.offset((i + k) as isize) as libc::c_int - * (*filter.offset(0))[k as usize] as libc::c_int; - k += 1; - } - *hor_ptr.offset(i as isize) = iclip( - sum + rounding_off_h >> round_bits_h, - 0 as libc::c_int, - clip_limit - 1, - ) as uint16_t; - i += 1; - } - tmp_ptr = tmp_ptr.offset(390); - hor_ptr = hor_ptr.offset(390); - j += 1; - } - let round_bits_v = 11 as libc::c_int - (bitdepth == 12) as libc::c_int * 2; - let rounding_off_v = (1 as libc::c_int) << round_bits_v - 1; - let round_offset = (1 as libc::c_int) << bitdepth + (round_bits_v - 1); - let mut j_0 = 0; - while j_0 < h { - let mut i_0 = 0; - while i_0 < w { - let mut sum_0 = -round_offset; - let mut k_0 = 0; - while k_0 < 7 { - sum_0 += hor[((j_0 + k_0) * 390 + i_0) as usize] as libc::c_int - * (*filter.offset(1))[k_0 as usize] as libc::c_int; - k_0 += 1; - } - *p.offset(j_0 as isize * PXSTRIDE(stride) + i_0 as isize) = iclip( - sum_0 + rounding_off_v >> round_bits_v, - 0 as libc::c_int, - bitdepth_max, - ) as pixel; - i_0 += 1; - } - j_0 += 1; - } -} unsafe extern "C" fn boxsum3( mut sumsq: *mut int32_t, mut sum: *mut coef, @@ -1268,7 +1177,7 @@ pub unsafe extern "C" fn dav1d_loop_restoration_dsp_init_16bpc( c: *mut Dav1dLoopRestorationDSPContext, _bpc: libc::c_int, ) { - (*c).wiener[1] = wiener_c; + (*c).wiener[1] = wiener_c_erased::; (*c).wiener[0] = (*c).wiener[1]; (*c).sgr[0] = sgr_5x5_c; (*c).sgr[1] = sgr_3x3_c; diff --git a/src/looprestoration_tmpl_8.rs b/src/looprestoration_tmpl_8.rs index 7356bc855..4039cdf8a 100644 --- a/src/looprestoration_tmpl_8.rs +++ b/src/looprestoration_tmpl_8.rs @@ -131,102 +131,14 @@ pub type coef = int16_t; use crate::src::looprestoration::LrEdgeFlags; pub type const_left_pixel_row = *const [pixel; 4]; use crate::src::looprestoration::padding; +use crate::src::looprestoration::wiener_c_erased; use crate::src::looprestoration::Dav1dLoopRestorationDSPContext; use crate::src::looprestoration::LooprestorationParams; -use crate::include::common::intops::iclip; use crate::include::common::intops::iclip_u8; use crate::include::common::intops::imax; use crate::include::common::intops::umin; -unsafe extern "C" fn wiener_c( - mut p: *mut libc::c_void, - stride: ptrdiff_t, - left: *const libc::c_void, - mut lpf: *const libc::c_void, - w: libc::c_int, - h: libc::c_int, - params: *const LooprestorationParams, - edges: LrEdgeFlags, - _bitdepth_max: libc::c_int, -) { - wiener_rust( - p.cast(), - stride, - left.cast(), - lpf.cast(), - w, - h, - params, - edges, - ) -} - -// TODO(randompoison): Temporarily public until we can move this to `looprestoration.rs`. -unsafe extern "C" fn wiener_rust( - mut p: *mut pixel, - stride: ptrdiff_t, - left: *const [pixel; 4], - mut lpf: *const pixel, - w: libc::c_int, - h: libc::c_int, - params: *const LooprestorationParams, - edges: LrEdgeFlags, -) { - let mut tmp: [pixel; 27300] = [0; 27300]; - let mut tmp_ptr: *mut pixel = tmp.as_mut_ptr(); - padding::(&mut tmp, p, stride, left, lpf, w, h, edges); - let mut hor: [uint16_t; 27300] = [0; 27300]; - let mut hor_ptr: *mut uint16_t = hor.as_mut_ptr(); - let filter: *const [int16_t; 8] = ((*params).filter.0).as_ptr(); - let bitdepth = 8; - let round_bits_h = 3 as libc::c_int + (bitdepth == 12) as libc::c_int * 2; - let rounding_off_h = (1 as libc::c_int) << round_bits_h - 1; - let clip_limit = (1 as libc::c_int) << bitdepth + 1 + 7 - round_bits_h; - let mut j = 0; - while j < h + 6 { - let mut i = 0; - while i < w { - let mut sum = (1 as libc::c_int) << bitdepth + 6; - sum += *tmp_ptr.offset((i + 3) as isize) as libc::c_int * 128; - let mut k = 0; - while k < 7 { - sum += *tmp_ptr.offset((i + k) as isize) as libc::c_int - * (*filter.offset(0))[k as usize] as libc::c_int; - k += 1; - } - *hor_ptr.offset(i as isize) = iclip( - sum + rounding_off_h >> round_bits_h, - 0 as libc::c_int, - clip_limit - 1, - ) as uint16_t; - i += 1; - } - tmp_ptr = tmp_ptr.offset(390); - hor_ptr = hor_ptr.offset(390); - j += 1; - } - let round_bits_v = 11 as libc::c_int - (bitdepth == 12) as libc::c_int * 2; - let rounding_off_v = (1 as libc::c_int) << round_bits_v - 1; - let round_offset = (1 as libc::c_int) << bitdepth + (round_bits_v - 1); - let mut j_0 = 0; - while j_0 < h { - let mut i_0 = 0; - while i_0 < w { - let mut sum_0 = -round_offset; - let mut k_0 = 0; - while k_0 < 7 { - sum_0 += hor[((j_0 + k_0) * 390 + i_0) as usize] as libc::c_int - * (*filter.offset(1))[k_0 as usize] as libc::c_int; - k_0 += 1; - } - *p.offset((j_0 as isize * stride + i_0 as isize) as isize) = - iclip_u8(sum_0 + rounding_off_v >> round_bits_v) as pixel; - i_0 += 1; - } - j_0 += 1; - } -} unsafe extern "C" fn boxsum3( mut sumsq: *mut int32_t, mut sum: *mut coef, @@ -1217,7 +1129,7 @@ pub unsafe extern "C" fn dav1d_loop_restoration_dsp_init_8bpc( c: *mut Dav1dLoopRestorationDSPContext, _bpc: libc::c_int, ) { - (*c).wiener[1] = wiener_c; + (*c).wiener[1] = wiener_c_erased::; (*c).wiener[0] = (*c).wiener[1]; (*c).sgr[0] = sgr_5x5_c; (*c).sgr[1] = sgr_3x3_c;