Keep track of relative pixel offsets and utilize pshufb to efficiently extract relevant pixels for horizontal scaling ratios <= 4. Fall back to a generic approach for ratios > 4. Note that the generic approach can be backported to SSE2. The implementation assumes that data beyond the end of each line, before the next line begins, can be dirtied; which AFAICT is safe with the current usage of these routines. Speedup is ~6.67x/~3.26x (32-bit/64-bit) for horizontal ratios <= 2, ~6.24x/~3.00x for ratios within (2, 4], and ~4.89x/~2.17x for ratios > 4 when not memory-bound on Haswell as compared with the current SSE2 implementation.
Showing the changes to codec/processing/src/downsample (3 of 6 files). Show all
Unified · Split
| @@ -100,6 +100,7 @@ void CDownsampling::InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int · 99 unmodified lines | ||
| 100 | 100 | sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsamplerWidthx16_ssse3; |
| 101 | 101 | sDownsampleFunc.pfOneThirdDownsampler = DyadicBilinearOneThirdDownsampler_ssse3; |
| 102 | 102 | sDownsampleFunc.pfQuarterDownsampler = DyadicBilinearQuarterDownsampler_ssse3; |
| 103 | + sDownsampleFunc.pfGeneralRatioLuma = GeneralBilinearFastDownsamplerWrap_ssse3; | |
| 103 | 104 | } |
| 104 | 105 | if (iCpuFlag & WELS_CPU_SSE41) { |
| 105 | 106 | sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsamplerWidthx32_sse4; |
| @@ -101,6 +101,7 @@ HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_sse4; · 100 unmodified lines | ||
| 101 | 101 | |
| 102 | 102 | GeneralDownsampleFunc GeneralBilinearFastDownsamplerWrap_sse2; |
| 103 | 103 | GeneralDownsampleFunc GeneralBilinearAccurateDownsamplerWrap_sse2; |
| 104 | +GeneralDownsampleFunc GeneralBilinearFastDownsamplerWrap_ssse3; | |
| 104 | 105 | |
| 105 | 106 | SpecificDownsampleFunc DyadicBilinearOneThirdDownsampler_ssse3; |
| 106 | 107 | SpecificDownsampleFunc DyadicBilinearOneThirdDownsampler_sse4; |
| @@ -114,6 +115,9 @@ void GeneralBilinearFastDownsampler_sse2 (uint8_t* pDst, const int32_t kiDstStri · 7 unmodified lines | ||
| 114 | 115 | void GeneralBilinearAccurateDownsampler_sse2 (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, |
| 115 | 116 | const int32_t kiDstHeight, uint8_t* pSrc, const int32_t kiSrcStride, const uint32_t kuiScaleX, |
| 116 | 117 | const uint32_t kuiScaleY); |
| 118 | +void GeneralBilinearFastDownsampler_ssse3 (uint8_t* pDst, int32_t iDstStride, int32_t iDstWidth, | |
| 119 | + int32_t iDstHeight, uint8_t* pSrc, int32_t iSrcStride, uint32_t uiScaleX, | |
| 120 | + uint32_t uiScaleY); | |
| 117 | 121 | |
| 118 | 122 | WELSVP_EXTERN_C_END |
| 119 | 123 | #endif |
| @@ -282,6 +282,7 @@ static void GeneralBilinearDownsamplerWrap (uint8_t* pDst, const int32_t kiDstSt · 281 unmodified lines | ||
| 282 | 282 | #ifdef X86_ASM |
| 283 | 283 | DEFINE_GENERAL_BILINEAR_FAST_DOWNSAMPLER_WRAP (sse2) |
| 284 | 284 | DEFINE_GENERAL_BILINEAR_ACCURATE_DOWNSAMPLER_WRAP (sse2) |
| 285 | +DEFINE_GENERAL_BILINEAR_FAST_DOWNSAMPLER_WRAP (ssse3) | |
| 285 | 286 | #endif //X86_ASM |
| 286 | 287 | |
| 287 | 288 | #ifdef HAVE_NEON |