masked_variance_intrin_ssse3.h (3850B)
1 /* 2 * Copyright (c) 2018, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #ifndef AOM_AOM_DSP_X86_MASKED_VARIANCE_INTRIN_SSSE3_H_ 13 #define AOM_AOM_DSP_X86_MASKED_VARIANCE_INTRIN_SSSE3_H_ 14 15 #include <stdlib.h> 16 #include <string.h> 17 #include <tmmintrin.h> 18 19 #include "config/aom_config.h" 20 #include "config/aom_dsp_rtcd.h" 21 22 #include "aom_dsp/blend.h" 23 24 static inline void comp_mask_pred_16_ssse3(const uint8_t *src0, 25 const uint8_t *src1, 26 const uint8_t *mask, uint8_t *dst) { 27 const __m128i alpha_max = _mm_set1_epi8(AOM_BLEND_A64_MAX_ALPHA); 28 const __m128i round_offset = 29 _mm_set1_epi16(1 << (15 - AOM_BLEND_A64_ROUND_BITS)); 30 31 const __m128i sA0 = _mm_lddqu_si128((const __m128i *)(src0)); 32 const __m128i sA1 = _mm_lddqu_si128((const __m128i *)(src1)); 33 const __m128i aA = _mm_load_si128((const __m128i *)(mask)); 34 35 const __m128i maA = _mm_sub_epi8(alpha_max, aA); 36 37 const __m128i ssAL = _mm_unpacklo_epi8(sA0, sA1); 38 const __m128i aaAL = _mm_unpacklo_epi8(aA, maA); 39 const __m128i ssAH = _mm_unpackhi_epi8(sA0, sA1); 40 const __m128i aaAH = _mm_unpackhi_epi8(aA, maA); 41 42 const __m128i blendAL = _mm_maddubs_epi16(ssAL, aaAL); 43 const __m128i blendAH = _mm_maddubs_epi16(ssAH, aaAH); 44 45 const __m128i roundAL = _mm_mulhrs_epi16(blendAL, round_offset); 46 const __m128i roundAH = _mm_mulhrs_epi16(blendAH, round_offset); 47 _mm_store_si128((__m128i *)dst, _mm_packus_epi16(roundAL, roundAH)); 48 } 49 50 static inline void comp_mask_pred_8_ssse3(uint8_t *comp_pred, int height, 51 const uint8_t *src0, int stride0, 52 const uint8_t *src1, int stride1, 53 const uint8_t *mask, 54 int mask_stride) { 55 int i = 0; 56 const __m128i alpha_max = _mm_set1_epi8(AOM_BLEND_A64_MAX_ALPHA); 57 const __m128i round_offset = 58 _mm_set1_epi16(1 << (15 - AOM_BLEND_A64_ROUND_BITS)); 59 do { 60 // odd line A 61 const __m128i sA0 = _mm_loadl_epi64((const __m128i *)(src0)); 62 const __m128i sA1 = _mm_loadl_epi64((const __m128i *)(src1)); 63 const __m128i aA = _mm_loadl_epi64((const __m128i *)(mask)); 64 // even line B 65 const __m128i sB0 = _mm_loadl_epi64((const __m128i *)(src0 + stride0)); 66 const __m128i sB1 = _mm_loadl_epi64((const __m128i *)(src1 + stride1)); 67 const __m128i a = _mm_castps_si128(_mm_loadh_pi( 68 _mm_castsi128_ps(aA), (const __m64 *)(mask + mask_stride))); 69 70 const __m128i ssA = _mm_unpacklo_epi8(sA0, sA1); 71 const __m128i ssB = _mm_unpacklo_epi8(sB0, sB1); 72 73 const __m128i ma = _mm_sub_epi8(alpha_max, a); 74 const __m128i aaA = _mm_unpacklo_epi8(a, ma); 75 const __m128i aaB = _mm_unpackhi_epi8(a, ma); 76 77 const __m128i blendA = _mm_maddubs_epi16(ssA, aaA); 78 const __m128i blendB = _mm_maddubs_epi16(ssB, aaB); 79 const __m128i roundA = _mm_mulhrs_epi16(blendA, round_offset); 80 const __m128i roundB = _mm_mulhrs_epi16(blendB, round_offset); 81 const __m128i round = _mm_packus_epi16(roundA, roundB); 82 // comp_pred's stride == width == 8 83 _mm_store_si128((__m128i *)(comp_pred), round); 84 comp_pred += (8 << 1); 85 src0 += (stride0 << 1); 86 src1 += (stride1 << 1); 87 mask += (mask_stride << 1); 88 i += 2; 89 } while (i < height); 90 } 91 92 #endif // AOM_AOM_DSP_X86_MASKED_VARIANCE_INTRIN_SSSE3_H_