Line data Source code
1 : /*
2 : * Copyright (c) 2016, 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 : #include <immintrin.h>
12 : #include "./aom_dsp_rtcd.h"
13 : #include "aom_ports/mem.h"
14 :
15 : #define FSAD64_H(h) \
16 : unsigned int aom_sad64x##h##_avx2(const uint8_t *src_ptr, int src_stride, \
17 : const uint8_t *ref_ptr, int ref_stride) { \
18 : int i, res; \
19 : __m256i sad1_reg, sad2_reg, ref1_reg, ref2_reg; \
20 : __m256i sum_sad = _mm256_setzero_si256(); \
21 : __m256i sum_sad_h; \
22 : __m128i sum_sad128; \
23 : for (i = 0; i < h; i++) { \
24 : ref1_reg = _mm256_loadu_si256((__m256i const *)ref_ptr); \
25 : ref2_reg = _mm256_loadu_si256((__m256i const *)(ref_ptr + 32)); \
26 : sad1_reg = _mm256_sad_epu8( \
27 : ref1_reg, _mm256_loadu_si256((__m256i const *)src_ptr)); \
28 : sad2_reg = _mm256_sad_epu8( \
29 : ref2_reg, _mm256_loadu_si256((__m256i const *)(src_ptr + 32))); \
30 : sum_sad = \
31 : _mm256_add_epi32(sum_sad, _mm256_add_epi32(sad1_reg, sad2_reg)); \
32 : ref_ptr += ref_stride; \
33 : src_ptr += src_stride; \
34 : } \
35 : sum_sad_h = _mm256_srli_si256(sum_sad, 8); \
36 : sum_sad = _mm256_add_epi32(sum_sad, sum_sad_h); \
37 : sum_sad128 = _mm256_extracti128_si256(sum_sad, 1); \
38 : sum_sad128 = _mm_add_epi32(_mm256_castsi256_si128(sum_sad), sum_sad128); \
39 : res = _mm_cvtsi128_si32(sum_sad128); \
40 : _mm256_zeroupper(); \
41 : return res; \
42 : }
43 :
44 : #define FSAD32_H(h) \
45 : unsigned int aom_sad32x##h##_avx2(const uint8_t *src_ptr, int src_stride, \
46 : const uint8_t *ref_ptr, int ref_stride) { \
47 : int i, res; \
48 : __m256i sad1_reg, sad2_reg, ref1_reg, ref2_reg; \
49 : __m256i sum_sad = _mm256_setzero_si256(); \
50 : __m256i sum_sad_h; \
51 : __m128i sum_sad128; \
52 : int ref2_stride = ref_stride << 1; \
53 : int src2_stride = src_stride << 1; \
54 : int max = h >> 1; \
55 : for (i = 0; i < max; i++) { \
56 : ref1_reg = _mm256_loadu_si256((__m256i const *)ref_ptr); \
57 : ref2_reg = _mm256_loadu_si256((__m256i const *)(ref_ptr + ref_stride)); \
58 : sad1_reg = _mm256_sad_epu8( \
59 : ref1_reg, _mm256_loadu_si256((__m256i const *)src_ptr)); \
60 : sad2_reg = _mm256_sad_epu8( \
61 : ref2_reg, \
62 : _mm256_loadu_si256((__m256i const *)(src_ptr + src_stride))); \
63 : sum_sad = \
64 : _mm256_add_epi32(sum_sad, _mm256_add_epi32(sad1_reg, sad2_reg)); \
65 : ref_ptr += ref2_stride; \
66 : src_ptr += src2_stride; \
67 : } \
68 : sum_sad_h = _mm256_srli_si256(sum_sad, 8); \
69 : sum_sad = _mm256_add_epi32(sum_sad, sum_sad_h); \
70 : sum_sad128 = _mm256_extracti128_si256(sum_sad, 1); \
71 : sum_sad128 = _mm_add_epi32(_mm256_castsi256_si128(sum_sad), sum_sad128); \
72 : res = _mm_cvtsi128_si32(sum_sad128); \
73 : _mm256_zeroupper(); \
74 : return res; \
75 : }
76 :
77 : #define FSAD64 \
78 : FSAD64_H(64); \
79 : FSAD64_H(32);
80 :
81 : #define FSAD32 \
82 : FSAD32_H(64); \
83 : FSAD32_H(32); \
84 : FSAD32_H(16);
85 :
86 : /* clang-format off */
87 0 : FSAD64
88 0 : FSAD32
89 : /* clang-format on */
90 :
91 : #undef FSAD64
92 : #undef FSAD32
93 : #undef FSAD64_H
94 : #undef FSAD32_H
95 :
96 : #define FSADAVG64_H(h) \
97 : unsigned int aom_sad64x##h##_avg_avx2( \
98 : const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \
99 : int ref_stride, const uint8_t *second_pred) { \
100 : int i, res; \
101 : __m256i sad1_reg, sad2_reg, ref1_reg, ref2_reg; \
102 : __m256i sum_sad = _mm256_setzero_si256(); \
103 : __m256i sum_sad_h; \
104 : __m128i sum_sad128; \
105 : for (i = 0; i < h; i++) { \
106 : ref1_reg = _mm256_loadu_si256((__m256i const *)ref_ptr); \
107 : ref2_reg = _mm256_loadu_si256((__m256i const *)(ref_ptr + 32)); \
108 : ref1_reg = _mm256_avg_epu8( \
109 : ref1_reg, _mm256_loadu_si256((__m256i const *)second_pred)); \
110 : ref2_reg = _mm256_avg_epu8( \
111 : ref2_reg, _mm256_loadu_si256((__m256i const *)(second_pred + 32))); \
112 : sad1_reg = _mm256_sad_epu8( \
113 : ref1_reg, _mm256_loadu_si256((__m256i const *)src_ptr)); \
114 : sad2_reg = _mm256_sad_epu8( \
115 : ref2_reg, _mm256_loadu_si256((__m256i const *)(src_ptr + 32))); \
116 : sum_sad = \
117 : _mm256_add_epi32(sum_sad, _mm256_add_epi32(sad1_reg, sad2_reg)); \
118 : ref_ptr += ref_stride; \
119 : src_ptr += src_stride; \
120 : second_pred += 64; \
121 : } \
122 : sum_sad_h = _mm256_srli_si256(sum_sad, 8); \
123 : sum_sad = _mm256_add_epi32(sum_sad, sum_sad_h); \
124 : sum_sad128 = _mm256_extracti128_si256(sum_sad, 1); \
125 : sum_sad128 = _mm_add_epi32(_mm256_castsi256_si128(sum_sad), sum_sad128); \
126 : res = _mm_cvtsi128_si32(sum_sad128); \
127 : _mm256_zeroupper(); \
128 : return res; \
129 : }
130 :
131 : #define FSADAVG32_H(h) \
132 : unsigned int aom_sad32x##h##_avg_avx2( \
133 : const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, \
134 : int ref_stride, const uint8_t *second_pred) { \
135 : int i, res; \
136 : __m256i sad1_reg, sad2_reg, ref1_reg, ref2_reg; \
137 : __m256i sum_sad = _mm256_setzero_si256(); \
138 : __m256i sum_sad_h; \
139 : __m128i sum_sad128; \
140 : int ref2_stride = ref_stride << 1; \
141 : int src2_stride = src_stride << 1; \
142 : int max = h >> 1; \
143 : for (i = 0; i < max; i++) { \
144 : ref1_reg = _mm256_loadu_si256((__m256i const *)ref_ptr); \
145 : ref2_reg = _mm256_loadu_si256((__m256i const *)(ref_ptr + ref_stride)); \
146 : ref1_reg = _mm256_avg_epu8( \
147 : ref1_reg, _mm256_loadu_si256((__m256i const *)second_pred)); \
148 : ref2_reg = _mm256_avg_epu8( \
149 : ref2_reg, _mm256_loadu_si256((__m256i const *)(second_pred + 32))); \
150 : sad1_reg = _mm256_sad_epu8( \
151 : ref1_reg, _mm256_loadu_si256((__m256i const *)src_ptr)); \
152 : sad2_reg = _mm256_sad_epu8( \
153 : ref2_reg, \
154 : _mm256_loadu_si256((__m256i const *)(src_ptr + src_stride))); \
155 : sum_sad = \
156 : _mm256_add_epi32(sum_sad, _mm256_add_epi32(sad1_reg, sad2_reg)); \
157 : ref_ptr += ref2_stride; \
158 : src_ptr += src2_stride; \
159 : second_pred += 64; \
160 : } \
161 : sum_sad_h = _mm256_srli_si256(sum_sad, 8); \
162 : sum_sad = _mm256_add_epi32(sum_sad, sum_sad_h); \
163 : sum_sad128 = _mm256_extracti128_si256(sum_sad, 1); \
164 : sum_sad128 = _mm_add_epi32(_mm256_castsi256_si128(sum_sad), sum_sad128); \
165 : res = _mm_cvtsi128_si32(sum_sad128); \
166 : _mm256_zeroupper(); \
167 : return res; \
168 : }
169 :
170 : #define FSADAVG64 \
171 : FSADAVG64_H(64); \
172 : FSADAVG64_H(32);
173 :
174 : #define FSADAVG32 \
175 : FSADAVG32_H(64); \
176 : FSADAVG32_H(32); \
177 : FSADAVG32_H(16);
178 :
179 : /* clang-format off */
180 0 : FSADAVG64
181 0 : FSADAVG32
182 : /* clang-format on */
183 :
184 : #undef FSADAVG64
185 : #undef FSADAVG32
186 : #undef FSADAVG64_H
187 : #undef FSADAVG32_H
|