filters/overlay/intel/OF_multiply_avx2.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Avisynth+ | ||
| 2 | // https://avs-plus.net | ||
| 3 | // | ||
| 4 | // This program is free software; you can redistribute it and/or modify | ||
| 5 | // it under the terms of the GNU General Public License as published by | ||
| 6 | // the Free Software Foundation; either version 2 of the License, or | ||
| 7 | // (at your option) any later version. | ||
| 8 | // | ||
| 9 | // This program is distributed in the hope that it will be useful, | ||
| 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | // GNU General Public License for more details. | ||
| 13 | // | ||
| 14 | // You should have received a copy of the GNU General Public License | ||
| 15 | // along with this program; if not, write to the Free Software | ||
| 16 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit | ||
| 17 | // http://www.gnu.org/copyleft/gpl.html . | ||
| 18 | // | ||
| 19 | // Linking Avisynth statically or dynamically with other modules is making a | ||
| 20 | // combined work based on Avisynth. Thus, the terms and conditions of the GNU | ||
| 21 | // General Public License cover the whole combination. | ||
| 22 | // | ||
| 23 | // As a special exception, the copyright holders of Avisynth give you | ||
| 24 | // permission to link Avisynth with independent modules that communicate with | ||
| 25 | // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license | ||
| 26 | // terms of these independent modules, and to copy and distribute the | ||
| 27 | // resulting combined work under terms of your choice, provided that | ||
| 28 | // every copy of the combined work is accompanied by a complete copy of | ||
| 29 | // the source code of Avisynth (the version of Avisynth used to produce the | ||
| 30 | // combined work), being distributed under the terms of the GNU General | ||
| 31 | // Public License plus this exception. An independent module is a module | ||
| 32 | // which is not derived from or based on Avisynth, such as 3rd-party filters, | ||
| 33 | // import and export plugins, or graphical user interfaces. | ||
| 34 | |||
| 35 | #include "avisynth.h" | ||
| 36 | #include "OF_multiply_avx2.h" | ||
| 37 | |||
| 38 | #include <stdint.h> | ||
| 39 | |||
| 40 | #ifdef _MSC_VER | ||
| 41 | #include <intrin.h> | ||
| 42 | #else | ||
| 43 | #include <x86intrin.h> | ||
| 44 | #endif | ||
| 45 | #include <immintrin.h> | ||
| 46 | |||
| 47 | template<typename pixel_t> | ||
| 48 | static AVS_FORCEINLINE __m256 Eightpixels_to_floats(const pixel_t* src) { | ||
| 49 | __m256i srci; | ||
| 50 | if constexpr (sizeof(pixel_t) == 1) { | ||
| 51 | 114 | srci = _mm256_cvtepu8_epi32(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src))); | |
| 52 | } | ||
| 53 | else { | ||
| 54 | 180 | srci = _mm256_cvtepu16_epi32(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src))); | |
| 55 | } | ||
| 56 | 147 | return _mm256_cvtepi32_ps(srci); | |
| 57 | } | ||
| 58 | |||
| 59 | template<typename pixel_t> | ||
| 60 | static AVS_FORCEINLINE __m256 EightChromapixels_to_floats(const pixel_t* src, const __m256i half) { | ||
| 61 | __m256i srci; | ||
| 62 | if constexpr (sizeof(pixel_t) == 1) { | ||
| 63 | 60 | srci = _mm256_cvtepu8_epi32(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src))); | |
| 64 | } | ||
| 65 | else { | ||
| 66 | 108 | srci = _mm256_cvtepu16_epi32(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src))); | |
| 67 | } | ||
| 68 | 84 | srci = _mm256_sub_epi32(srci, half); | |
| 69 | 84 | return _mm256_cvtepi32_ps(srci); | |
| 70 | } | ||
| 71 | |||
| 72 | template<typename pixel_t> | ||
| 73 | static AVS_FORCEINLINE void Store_Eightpixels(pixel_t* dst, __m256 what, const __m256 rounder) { | ||
| 74 | 42 | what = _mm256_add_ps(what, rounder); // round | |
| 75 | 42 | __m256i si32 = _mm256_cvttps_epi32(what); // truncate | |
| 76 | 42 | __m256i result = _mm256_packus_epi32(si32, si32); // only low 8 words needed | |
| 77 | 42 | result = _mm256_permute4x64_epi64(result, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); | |
| 78 | 42 | __m128i result128 = _mm256_castsi256_si128(result); | |
| 79 | if constexpr (sizeof(pixel_t) == 1) { | ||
| 80 | 15 | __m128i result64 = _mm_packus_epi16(result128, result128); | |
| 81 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dst), result64); | ||
| 82 | } else { | ||
| 83 | _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), result128); | ||
| 84 | } | ||
| 85 | 42 | } | |
| 86 | |||
| 87 | template<typename pixel_t> | ||
| 88 | static AVS_FORCEINLINE void Store_EightChromapixels(pixel_t* dst, __m256 what, const __m256 half_plus_rounder) { | ||
| 89 | 84 | what = _mm256_add_ps(what, half_plus_rounder); // chroma offset back with rounder | |
| 90 | 84 | __m256i si32 = _mm256_cvttps_epi32(what); // truncate | |
| 91 | 84 | __m256i result = _mm256_packus_epi32(si32, si32); // only low 8 words needed | |
| 92 | 84 | result = _mm256_permute4x64_epi64(result, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); | |
| 93 | 84 | __m128i result128 = _mm256_castsi256_si128(result); | |
| 94 | if constexpr (sizeof(pixel_t) == 1) { | ||
| 95 | 30 | __m128i result64 = _mm_packus_epi16(result128, result128); | |
| 96 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dst), result64); | ||
| 97 | } | ||
| 98 | else { | ||
| 99 | _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), result128); | ||
| 100 | } | ||
| 101 | 84 | } | |
| 102 | |||
| 103 | |||
| 104 | template<typename pixel_t, bool opacity_is_full, bool has_mask> | ||
| 105 | #if defined(GCC) || defined(CLANG) | ||
| 106 | __attribute__((__target__("avx2"))) | ||
| 107 | #endif | ||
| 108 | 14 | void of_multiply_avx2( | |
| 109 | int bits_per_pixel, | ||
| 110 | const float opacity_f, | ||
| 111 | const int opacity, | ||
| 112 | int width, int height, | ||
| 113 | const pixel_t* ovY, | ||
| 114 | int overlaypitch, | ||
| 115 | pixel_t* baseY, pixel_t* baseU, pixel_t* baseV, | ||
| 116 | int basepitch, | ||
| 117 | const pixel_t* maskY, const pixel_t* maskU, const pixel_t* maskV, | ||
| 118 | int maskpitch | ||
| 119 | ) | ||
| 120 | { | ||
| 121 | 14 | const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1; | |
| 122 | 14 | const float factor = 1.0f / max_pixel_value; | |
| 123 | 14 | const int half_i = sizeof(pixel_t) == 1 ? 128 : 1 << (bits_per_pixel - 1); | |
| 124 | 14 | const float half_f = (float)half_i; | |
| 125 | |||
| 126 | float factor_mul_opacity; | ||
| 127 | if constexpr (opacity_is_full) | ||
| 128 | 6 | factor_mul_opacity = factor * 1.0f; | |
| 129 | else | ||
| 130 | 8 | factor_mul_opacity = factor * opacity_f; | |
| 131 | |||
| 132 | 14 | auto opacity_simd = _mm256_set1_ps(opacity_f); | |
| 133 | 14 | auto factor_simd = _mm256_set1_ps(factor); | |
| 134 | 14 | auto factor_mul_opacity_simd = _mm256_set1_ps(factor_mul_opacity); | |
| 135 | 14 | auto one_ps_simd = _mm256_set1_ps(1.0f); | |
| 136 | 14 | const __m256i half_i_simd = _mm256_set1_epi32(half_i); | |
| 137 | 23 | const __m256 half_and_rounder_simd = _mm256_set1_ps(half_f + 0.5f); | |
| 138 | 14 | const __m256 rounder_simd = _mm256_set1_ps(0.5f); | |
| 139 | |||
| 140 | 14 | const int wMod8 = width / 8 * 8; | |
| 141 | |||
| 142 | // start processing | ||
| 143 |
16/16void of_multiply_avx2<unsigned char, false, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 126 → 17 taken 3 times.
✓ Branch 126 → 127 taken 1 time.
void of_multiply_avx2<unsigned char, false, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 176 → 17 taken 6 times.
✓ Branch 176 → 177 taken 2 times.
void of_multiply_avx2<unsigned char, true, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 126 → 17 taken 3 times.
✓ Branch 126 → 127 taken 1 time.
void of_multiply_avx2<unsigned char, true, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 176 → 17 taken 3 times.
✓ Branch 176 → 177 taken 1 time.
void of_multiply_avx2<unsigned short, false, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 104 → 17 taken 9 times.
✓ Branch 104 → 105 taken 3 times.
void of_multiply_avx2<unsigned short, false, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 142 → 17 taken 6 times.
✓ Branch 142 → 143 taken 2 times.
void of_multiply_avx2<unsigned short, true, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 104 → 17 taken 6 times.
✓ Branch 104 → 105 taken 2 times.
void of_multiply_avx2<unsigned short, true, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 142 → 17 taken 6 times.
✓ Branch 142 → 143 taken 2 times.
|
56 | for (int y = 0; y < height; y++) { |
| 144 |
16/16void of_multiply_avx2<unsigned char, false, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 121 → 18 taken 3 times.
✓ Branch 121 → 122 taken 3 times.
void of_multiply_avx2<unsigned char, false, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 171 → 18 taken 6 times.
✓ Branch 171 → 172 taken 6 times.
void of_multiply_avx2<unsigned char, true, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 121 → 18 taken 3 times.
✓ Branch 121 → 122 taken 3 times.
void of_multiply_avx2<unsigned char, true, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 171 → 18 taken 3 times.
✓ Branch 171 → 172 taken 3 times.
void of_multiply_avx2<unsigned short, false, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 99 → 18 taken 9 times.
✓ Branch 99 → 100 taken 9 times.
void of_multiply_avx2<unsigned short, false, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 137 → 18 taken 6 times.
✓ Branch 137 → 138 taken 6 times.
void of_multiply_avx2<unsigned short, true, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 99 → 18 taken 6 times.
✓ Branch 99 → 100 taken 6 times.
void of_multiply_avx2<unsigned short, true, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 137 → 18 taken 6 times.
✓ Branch 137 → 138 taken 6 times.
|
84 | for (int x = 0; x < wMod8; x += 8) { |
| 145 | __m256 Y, U, V; | ||
| 146 | // 8 pixels at a time. 8 or 16 bits to floats | ||
| 147 | 84 | __m256 ovY_ps = Eightpixels_to_floats<pixel_t>(ovY + x); | |
| 148 | |||
| 149 | // generic, 8-16 bits | ||
| 150 | if constexpr (has_mask) { | ||
| 151 | __m256 final_opacity; | ||
| 152 | 21 | auto overlay_opacity_minus1 = _mm256_sub_ps(_mm256_mul_ps(ovY_ps, factor_simd), one_ps_simd); // ovY[x] * factor - 1.0f; | |
| 153 | |||
| 154 | 42 | __m256 maskY_ps = Eightpixels_to_floats<pixel_t>(maskY + x); | |
| 155 | 21 | final_opacity = _mm256_mul_ps(maskY_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity; | |
| 156 | 21 | auto Yfactor = _mm256_add_ps(one_ps_simd, _mm256_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity; | |
| 157 | 42 | __m256 baseY_ps = Eightpixels_to_floats<pixel_t>(baseY + x); | |
| 158 | 21 | Y = _mm256_mul_ps(baseY_ps, Yfactor); // Y = (int)(baseY[x] * Yfactor); | |
| 159 | |||
| 160 | 42 | __m256 maskU_ps = Eightpixels_to_floats<pixel_t>(maskU + x); | |
| 161 | 21 | final_opacity = _mm256_mul_ps(maskU_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity; | |
| 162 | 21 | auto Ufactor = _mm256_add_ps(one_ps_simd, _mm256_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity; | |
| 163 | 42 | __m256 baseU_ps = EightChromapixels_to_floats<pixel_t>(baseU + x, half_i_simd); | |
| 164 | 21 | U = _mm256_mul_ps(baseU_ps, Ufactor); // U = (int)((baseU[x] - half_i) * Ufactor) not yet: + half_i; | |
| 165 | |||
| 166 | 42 | __m256 maskV_ps = Eightpixels_to_floats<pixel_t>(maskV + x); | |
| 167 | 21 | final_opacity = _mm256_mul_ps(maskV_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity; | |
| 168 | 21 | auto Vfactor = _mm256_add_ps(one_ps_simd, _mm256_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity; | |
| 169 | 42 | __m256 baseV_ps = EightChromapixels_to_floats<pixel_t>(baseV + x, half_i_simd); | |
| 170 | 21 | V = _mm256_mul_ps(baseV_ps, Vfactor); // V = (int)((baseV[x] - half_i) * Vfactor) not yet: + half_i; | |
| 171 | |||
| 172 | } | ||
| 173 | else { | ||
| 174 | 42 | auto overlay_opacity_minus1 = _mm256_sub_ps(_mm256_mul_ps(ovY_ps, factor_simd), one_ps_simd); // ovY[x] * factor - 1.0f; | |
| 175 | 21 | auto common_factor = _mm256_add_ps(one_ps_simd, _mm256_mul_ps(overlay_opacity_minus1, opacity_simd)); // 1.0f + overlay_opacity_minus1 * opacity_f; | |
| 176 | |||
| 177 | 21 | auto Yfactor = common_factor; | |
| 178 | 42 | __m256 baseY_ps = Eightpixels_to_floats<pixel_t>(baseY + x); | |
| 179 | 21 | Y = _mm256_mul_ps(baseY_ps, Yfactor); // Y = (int)(baseY[x] * Yfactor); | |
| 180 | |||
| 181 | 21 | auto Ufactor = common_factor; | |
| 182 | 42 | __m256 baseU_ps = EightChromapixels_to_floats<pixel_t>(baseU + x, half_i_simd); | |
| 183 | 21 | U = _mm256_mul_ps(baseU_ps, Ufactor); // U = (int)((baseU[x] - half_i) * Ufactor) not yet: + half_i; | |
| 184 | |||
| 185 | 21 | auto Vfactor = common_factor; | |
| 186 | 42 | __m256 baseV_ps = EightChromapixels_to_floats<pixel_t>(baseV + x, half_i_simd); | |
| 187 | 21 | V = _mm256_mul_ps(baseV_ps, Vfactor); // V = (int)((baseV[x] - half_i) * Vfactor) not yet: + half_i; | |
| 188 | |||
| 189 | } | ||
| 190 | |||
| 191 | 42 | Store_Eightpixels<pixel_t>(baseY + x, Y, rounder_simd); | |
| 192 | 42 | Store_EightChromapixels<pixel_t>(baseU + x, U, half_and_rounder_simd); | |
| 193 | 42 | Store_EightChromapixels<pixel_t>(baseV + x, V, half_and_rounder_simd); | |
| 194 | |||
| 195 | } | ||
| 196 | |||
| 197 |
16/16void of_multiply_avx2<unsigned char, false, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 124 → 123 taken 9 times.
✓ Branch 124 → 125 taken 3 times.
void of_multiply_avx2<unsigned char, false, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 174 → 173 taken 18 times.
✓ Branch 174 → 175 taken 6 times.
void of_multiply_avx2<unsigned char, true, false>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 124 → 123 taken 9 times.
✓ Branch 124 → 125 taken 3 times.
void of_multiply_avx2<unsigned char, true, true>(int, float, int, int, int, unsigned char const*, int, unsigned char*, unsigned char*, unsigned char*, int, unsigned char const*, unsigned char const*, unsigned char const*, int):
✓ Branch 174 → 173 taken 9 times.
✓ Branch 174 → 175 taken 3 times.
void of_multiply_avx2<unsigned short, false, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 102 → 101 taken 27 times.
✓ Branch 102 → 103 taken 9 times.
void of_multiply_avx2<unsigned short, false, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 140 → 139 taken 18 times.
✓ Branch 140 → 141 taken 6 times.
void of_multiply_avx2<unsigned short, true, false>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 102 → 101 taken 18 times.
✓ Branch 102 → 103 taken 6 times.
void of_multiply_avx2<unsigned short, true, true>(int, float, int, int, int, unsigned short const*, int, unsigned short*, unsigned short*, unsigned short*, int, unsigned short const*, unsigned short const*, unsigned short const*, int):
✓ Branch 140 → 139 taken 18 times.
✓ Branch 140 → 141 taken 6 times.
|
168 | for (int x = wMod8; x < width; x++) { |
| 198 | // from of_mul_c | ||
| 199 | int Y, U, V; | ||
| 200 | |||
| 201 | // generic, 8-16 bits | ||
| 202 | // This part re-appears in SSE2 code (non mod4 end-of-line fragment) | ||
| 203 | // Unlike the old integer version here is proper rounding | ||
| 204 | 126 | const float overlay_opacity_minus1 = ovY[x] * factor - 1.0f; | |
| 205 | if constexpr (has_mask) { | ||
| 206 | float final_opacity; | ||
| 207 | |||
| 208 | 63 | final_opacity = maskY[x] * factor_mul_opacity; | |
| 209 | 63 | auto Yfactor = 1.0f + overlay_opacity_minus1 * final_opacity; | |
| 210 | 63 | Y = (int)(baseY[x] * Yfactor + 0.5f); | |
| 211 | |||
| 212 | 63 | final_opacity = maskU[x] * factor_mul_opacity; | |
| 213 | 63 | auto Ufactor = 1.0f + overlay_opacity_minus1 * final_opacity; | |
| 214 | 63 | U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f); | |
| 215 | |||
| 216 | 63 | final_opacity = maskV[x] * factor_mul_opacity; | |
| 217 | 63 | auto Vfactor = 1.0f + overlay_opacity_minus1 * final_opacity; | |
| 218 | 63 | V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f); | |
| 219 | } | ||
| 220 | else { | ||
| 221 | 63 | const float common_factor = 1.0f + overlay_opacity_minus1 * opacity_f; | |
| 222 | |||
| 223 | 63 | auto Yfactor = common_factor; | |
| 224 | 63 | Y = (int)((float)baseY[x] * Yfactor + 0.5f); | |
| 225 | |||
| 226 | 63 | auto Ufactor = common_factor; | |
| 227 | 63 | U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f); | |
| 228 | |||
| 229 | 63 | auto Vfactor = common_factor; | |
| 230 | 63 | V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f); | |
| 231 | |||
| 232 | } | ||
| 233 | |||
| 234 | 126 | baseU[x] = (pixel_t)U; | |
| 235 | 126 | baseV[x] = (pixel_t)V; | |
| 236 | 126 | baseY[x] = (pixel_t)Y; | |
| 237 | } | ||
| 238 | |||
| 239 | if constexpr (has_mask) { | ||
| 240 | 21 | maskY += maskpitch; | |
| 241 | 21 | maskU += maskpitch; | |
| 242 | 21 | maskV += maskpitch; | |
| 243 | } | ||
| 244 | |||
| 245 | 42 | baseY += basepitch; | |
| 246 | 42 | baseU += basepitch; | |
| 247 | 42 | baseV += basepitch; | |
| 248 | |||
| 249 | 42 | ovY += overlaypitch; | |
| 250 | |||
| 251 | } | ||
| 252 | 14 | } | |
| 253 | |||
| 254 | // instantiate | ||
| 255 | template void of_multiply_avx2<uint8_t, false, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height, | ||
| 256 | const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch); | ||
| 257 | template void of_multiply_avx2<uint8_t, false, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height, | ||
| 258 | const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch); | ||
| 259 | template void of_multiply_avx2<uint8_t, true, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height, | ||
| 260 | const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch); | ||
| 261 | template void of_multiply_avx2<uint8_t, true, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height, | ||
| 262 | const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch); | ||
| 263 | template void of_multiply_avx2<uint16_t, false, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height, | ||
| 264 | const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch); | ||
| 265 | template void of_multiply_avx2<uint16_t, false, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height, | ||
| 266 | const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch); | ||
| 267 | template void of_multiply_avx2<uint16_t, true, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height, | ||
| 268 | const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch); | ||
| 269 | template void of_multiply_avx2<uint16_t, true, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height, | ||
| 270 | const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch); | ||
| 271 | |||
| 272 |