filters/intel/turn_sse.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al. | ||
| 2 | // http://avisynth.nl | ||
| 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 | /* | ||
| 36 | ** Turn. version 0.1 | ||
| 37 | ** (c) 2003 - Ernst Peché | ||
| 38 | ** | ||
| 39 | */ | ||
| 40 | |||
| 41 | #include "../turn.h" | ||
| 42 | #include "turn_sse.h" | ||
| 43 | |||
| 44 | // Intrinsics base header + really required extension headers | ||
| 45 | #if defined(_MSC_VER) | ||
| 46 | #include <intrin.h> // MSVC | ||
| 47 | #else | ||
| 48 | #include <x86intrin.h> // GCC/MinGW/Clang/LLVM | ||
| 49 | #endif | ||
| 50 | #include <tmmintrin.h> // SSSE3 | ||
| 51 | |||
| 52 | #include <cstdint> | ||
| 53 | |||
| 54 | |||
| 55 | static AVS_FORCEINLINE __m128i movehl(const __m128i& x) | ||
| 56 | { | ||
| 57 | 128 | __m128 ps = _mm_castsi128_ps(x); | |
| 58 | 128 | return _mm_castps_si128(_mm_movehl_ps(ps, ps)); | |
| 59 | } | ||
| 60 | |||
| 61 | |||
| 62 | // This pattern seems faster than the others. | ||
| 63 | static AVS_FORCEINLINE void transpose_8x8x8_sse2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, int src_pitch, int dst_pitch) | ||
| 64 | { | ||
| 65 | 16 | __m128i a07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 0)); //a0 a1 a2 a3 a4 a5 a6 a7 | |
| 66 | 16 | __m128i b07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 1)); //b0 b1 b2 b3 b4 b5 b6 b7 | |
| 67 | 16 | __m128i c07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 2)); //c0 c1 c2 c3 c4 c5 c6 c7 | |
| 68 | 16 | __m128i d07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 3)); //d0 d1 d2 d3 d4 d5 d6 d7 | |
| 69 | 16 | __m128i e07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 4)); //e0 e1 e2 e3 e4 e5 e6 e7 | |
| 70 | 16 | __m128i f07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 5)); //f0 f1 f2 f3 f4 f5 f6 f7 | |
| 71 | 16 | __m128i g07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 6)); //g0 g1 g2 g3 g4 g5 g6 g7 | |
| 72 | 32 | __m128i h07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 7)); //h0 h1 h2 h3 h4 h5 h6 h7 | |
| 73 | |||
| 74 | 16 | __m128i ea07 = _mm_unpacklo_epi8(e07, a07); //e0 a0 e1 a1 e2 a2 e3 a3 e4 a4 e5 a5 e6 a6 e7 a7 | |
| 75 | 16 | __m128i fb07 = _mm_unpacklo_epi8(f07, b07); //f0 b0 f1 b1 f2 b2 f3 b3 f4 b4 f5 b5 f6 b6 f7 b7 | |
| 76 | 16 | __m128i gc07 = _mm_unpacklo_epi8(g07, c07); //g0 c0 g1 c1 g2 c2 g3 c3 g4 c4 g5 c5 g6 c6 g7 c7 | |
| 77 | 16 | __m128i hd07 = _mm_unpacklo_epi8(h07, d07); //h0 d0 h1 d1 h2 d2 h3 d3 h4 d4 h5 d5 h6 d6 h7 d7 | |
| 78 | |||
| 79 | 16 | __m128i geca03 = _mm_unpacklo_epi8(gc07, ea07); //g0 e0 c0 a0 g1 e1 c1 a1 g2 e2 c2 a2 g3 e3 c3 a3 | |
| 80 | 16 | __m128i geca47 = _mm_unpackhi_epi8(gc07, ea07); //g4 e4 c4 a4 g5 e5 c5 a5 g6 e6 c6 a6 g7 e7 c7 a7 | |
| 81 | 16 | __m128i hfdb03 = _mm_unpacklo_epi8(hd07, fb07); //h0 f0 d0 b0 h1 f1 d1 b1 h2 f2 d2 b2 h3 f3 d3 b3 | |
| 82 | 16 | __m128i hfdb47 = _mm_unpackhi_epi8(hd07, fb07); //h4 f4 d4 b4 h5 f5 d5 b5 h6 f6 d6 b6 h7 f7 d7 b7 | |
| 83 | |||
| 84 | 16 | __m128i hgfedcba01 = _mm_unpacklo_epi8(hfdb03, geca03); //h0 g0 f0 e0 d0 c0 b0 a0 h1 g1 f1 e1 d1 c1 b1 a1 | |
| 85 | 16 | __m128i hgfedcba23 = _mm_unpackhi_epi8(hfdb03, geca03); //h2 g2 f2 e2 d2 c2 b2 a2 h3 g3 f3 e3 d3 c3 b3 a3 | |
| 86 | 16 | __m128i hgfedcba45 = _mm_unpacklo_epi8(hfdb47, geca47); //h4 g4 f4 e4 d4 c4 b4 a4 h5 g5 f5 e5 d5 c5 b5 a5 | |
| 87 | 16 | __m128i hgfedcba67 = _mm_unpackhi_epi8(hfdb47, geca47); //h6 g6 f6 e6 d6 c6 b6 a6 h7 g7 f7 e7 d7 c7 b7 a7 | |
| 88 | |||
| 89 | 16 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 0), hgfedcba01); | |
| 90 | 16 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 1), movehl(hgfedcba01)); | |
| 91 | 16 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 2), hgfedcba23); | |
| 92 | 16 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 3), movehl(hgfedcba23)); | |
| 93 | 16 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 4), hgfedcba45); | |
| 94 | 16 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 5), movehl(hgfedcba45)); | |
| 95 | 16 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 6), hgfedcba67); | |
| 96 | 16 | _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 7), movehl(hgfedcba67)); | |
| 97 | 16 | } | |
| 98 | |||
| 99 | |||
| 100 | 2 | void turn_right_plane_8_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 101 | { | ||
| 102 | 2 | const BYTE* s0 = srcp; | |
| 103 | 2 | int w = src_rowsize & ~7; | |
| 104 | 2 | int h = src_height & ~7; | |
| 105 | |||
| 106 |
2/2✓ Branch 120 → 3 taken 4 times.
✓ Branch 120 → 121 taken 2 times.
|
6 | for (int y = 0; y < h; y += 8) |
| 107 | { | ||
| 108 | 4 | BYTE* d0 = dstp + src_height - 8 - y; | |
| 109 |
2/2✓ Branch 118 → 4 taken 16 times.
✓ Branch 118 → 119 taken 4 times.
|
20 | for (int x = 0; x < w; x += 8) |
| 110 | { | ||
| 111 | 16 | transpose_8x8x8_sse2(s0 + x, d0, src_pitch, dst_pitch); | |
| 112 | 16 | d0 += dst_pitch * 8; | |
| 113 | } | ||
| 114 | 4 | s0 += src_pitch * 8; | |
| 115 | } | ||
| 116 | |||
| 117 |
1/2✓ Branch 121 → 122 taken 2 times.
✗ Branch 121 → 123 not taken.
|
2 | if (src_rowsize != w) |
| 118 | { | ||
| 119 | 2 | turn_right_plane_8_c(srcp + w, dstp + w * dst_pitch, src_rowsize - w, src_height, src_pitch, dst_pitch); | |
| 120 | } | ||
| 121 | |||
| 122 |
1/2✓ Branch 123 → 124 taken 2 times.
✗ Branch 123 → 125 not taken.
|
2 | if (src_height != h) |
| 123 | { | ||
| 124 | 2 | turn_right_plane_8_c(srcp + h * src_pitch, dstp, src_rowsize, src_height - h, src_pitch, dst_pitch); | |
| 125 | } | ||
| 126 | 2 | } | |
| 127 | |||
| 128 | |||
| 129 | 1 | void turn_left_plane_8_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 130 | { | ||
| 131 | 1 | turn_right_plane_8_sse2(srcp + (src_height - 1) * src_pitch, dstp + (src_rowsize - 1) * dst_pitch, src_rowsize, src_height, -src_pitch, -dst_pitch); | |
| 132 | 1 | } | |
| 133 | |||
| 134 | |||
| 135 | |||
| 136 | static AVS_FORCEINLINE void transpose_16x4x8_sse2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, const int src_pitch, const int dst_pitch) | ||
| 137 | { | ||
| 138 | 16 | __m128i a03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 0)); //a0 a1 a2 a3 | |
| 139 | 16 | __m128i b03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 1)); //b0 b1 b2 b3 | |
| 140 | 16 | __m128i c03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 2)); //c0 c1 c2 c3 | |
| 141 | 16 | __m128i d03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 3)); //d0 d1 d2 d3 | |
| 142 | 16 | __m128i e03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 4)); //e0 e1 e2 e3 | |
| 143 | 16 | __m128i f03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 5)); //f0 f1 f2 f3 | |
| 144 | 16 | __m128i g03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 6)); //g0 g1 g2 g3 | |
| 145 | 32 | __m128i h03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 7)); //h0 h1 h2 h3 | |
| 146 | |||
| 147 | 16 | __m128i ae03 = _mm_unpacklo_epi16(a03, e03); //a0 e0 a1 e1 a2 e2 a3 e3 | |
| 148 | 16 | __m128i bf03 = _mm_unpacklo_epi16(b03, f03); //b0 f0 b1 f1 b2 f2 b3 f3 | |
| 149 | 16 | __m128i cg03 = _mm_unpacklo_epi16(c03, g03); //c0 g0 c1 g1 c2 g2 c3 g3 | |
| 150 | 16 | __m128i dh03 = _mm_unpacklo_epi16(d03, h03); //d0 h0 d1 h1 d2 h2 d3 h3 | |
| 151 | |||
| 152 | 16 | __m128i aceg01 = _mm_unpacklo_epi16(ae03, cg03); //a0 c0 e0 g0 a1 c1 e1 g1 | |
| 153 | 16 | __m128i aceg23 = _mm_unpackhi_epi16(ae03, cg03); //a2 c2 e2 g2 a3 c3 e3 g3 | |
| 154 | 16 | __m128i bdfh01 = _mm_unpacklo_epi16(bf03, dh03); //b0 d0 f0 h0 b1 d1 f1 h1 | |
| 155 | 16 | __m128i bdfh23 = _mm_unpackhi_epi16(bf03, dh03); //b2 d2 f2 h2 b3 d3 f3 h3 | |
| 156 | |||
| 157 | 16 | __m128i abcdefgh0 = _mm_unpacklo_epi16(aceg01, bdfh01); //a0 b0 c0 d0 e0 f0 g0 h0 | |
| 158 | 16 | __m128i abcdefgh1 = _mm_unpackhi_epi16(aceg01, bdfh01); //a1 b1 c1 d1 e1 f1 g1 h1 | |
| 159 | 16 | __m128i abcdefgh2 = _mm_unpacklo_epi16(aceg23, bdfh23); //a2 b2 c2 d2 e2 f2 g2 h2 | |
| 160 | 16 | __m128i abcdefgh3 = _mm_unpackhi_epi16(aceg23, bdfh23); //a3 b3 c3 d3 e3 f3 g3 h3 | |
| 161 | |||
| 162 | _mm_store_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 0), abcdefgh0); | ||
| 163 | 16 | _mm_store_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 1), abcdefgh1); | |
| 164 | 16 | _mm_store_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 2), abcdefgh2); | |
| 165 | 16 | _mm_store_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 3), abcdefgh3); | |
| 166 | 16 | } | |
| 167 | |||
| 168 | |||
| 169 | 2 | void turn_right_plane_16_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 170 | { | ||
| 171 | 2 | const BYTE* s0 = srcp + src_pitch * (src_height - 1); | |
| 172 | 2 | int w = src_rowsize & ~7; | |
| 173 | 2 | int h = src_height & ~7; | |
| 174 | |||
| 175 |
2/2✓ Branch 84 → 3 taken 4 times.
✓ Branch 84 → 85 taken 2 times.
|
6 | for (int y = 0; y < h; y += 8) |
| 176 | { | ||
| 177 | 4 | BYTE* d0 = dstp + y * 2; | |
| 178 |
2/2✓ Branch 82 → 4 taken 16 times.
✓ Branch 82 → 83 taken 4 times.
|
20 | for (int x = 0; x < w; x += 8) |
| 179 | { | ||
| 180 | 16 | transpose_16x4x8_sse2(s0 + x, d0, -src_pitch, dst_pitch); | |
| 181 | 16 | d0 += 4 * dst_pitch; | |
| 182 | } | ||
| 183 | 4 | s0 -= 8 * src_pitch; | |
| 184 | } | ||
| 185 |
1/2✓ Branch 85 → 86 taken 2 times.
✗ Branch 85 → 87 not taken.
|
2 | if (src_rowsize != w) |
| 186 | { | ||
| 187 | 2 | turn_right_plane_16_c(srcp + w, dstp + dst_pitch * w / 2, src_rowsize - w, src_height, src_pitch, dst_pitch); | |
| 188 | } | ||
| 189 | |||
| 190 |
1/2✓ Branch 87 → 88 taken 2 times.
✗ Branch 87 → 89 not taken.
|
2 | if (src_height != h) |
| 191 | { | ||
| 192 | 2 | turn_right_plane_16_c(srcp, dstp + h * 2, src_rowsize, src_height - h, src_pitch, dst_pitch); | |
| 193 | } | ||
| 194 | 2 | } | |
| 195 | |||
| 196 | |||
| 197 | 1 | void turn_left_plane_16_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 198 | { | ||
| 199 | 1 | turn_right_plane_16_sse2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 2 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch); | |
| 200 | 1 | } | |
| 201 | |||
| 202 | |||
| 203 | |||
| 204 | static AVS_FORCEINLINE void transpose_32x4x4_sse2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, const int src_pitch, const int dst_pitch) | ||
| 205 | { | ||
| 206 | 16 | __m128i a03 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + src_pitch * 0)); //a0 a1 a2 a3 | |
| 207 | 16 | __m128i b03 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + src_pitch * 1)); //b0 b1 b2 b3 | |
| 208 | 16 | __m128i c03 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + src_pitch * 2)); //c0 c1 c2 c3 | |
| 209 | 32 | __m128i d03 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + src_pitch * 3)); //d0 d1 d2 d3 | |
| 210 | |||
| 211 | 16 | __m128i ac01 = _mm_unpacklo_epi32(a03, c03); //a0 c0 a1 c1 | |
| 212 | 16 | __m128i ac23 = _mm_unpackhi_epi32(a03, c03); //a2 c2 a3 c3 | |
| 213 | 16 | __m128i bd01 = _mm_unpacklo_epi32(b03, d03); //b0 d0 b1 d1 | |
| 214 | 16 | __m128i bd23 = _mm_unpackhi_epi32(b03, d03); //b2 d2 b3 d3 | |
| 215 | |||
| 216 | 16 | __m128i abcd0 = _mm_unpacklo_epi32(ac01, bd01); //a0 b0 c0 d0 | |
| 217 | 16 | __m128i abcd1 = _mm_unpackhi_epi32(ac01, bd01); //a1 b1 c1 d1 | |
| 218 | 16 | __m128i abcd2 = _mm_unpacklo_epi32(ac23, bd23); //a2 b2 c2 d2 | |
| 219 | 16 | __m128i abcd3 = _mm_unpackhi_epi32(ac23, bd23); //a3 b3 c3 d3 | |
| 220 | |||
| 221 | _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 0), abcd0); | ||
| 222 | 16 | _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 1), abcd1); | |
| 223 | 16 | _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 2), abcd2); | |
| 224 | 16 | _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 3), abcd3); | |
| 225 | 16 | } | |
| 226 | |||
| 227 | |||
| 228 | 4 | void turn_right_plane_32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 229 | { | ||
| 230 | 4 | const BYTE* s0 = srcp + src_pitch * (src_height - 1); | |
| 231 | 4 | int w = src_rowsize & ~15; | |
| 232 | 4 | int h = src_height & ~3; | |
| 233 | |||
| 234 |
2/2✓ Branch 36 → 3 taken 8 times.
✓ Branch 36 → 37 taken 4 times.
|
12 | for (int y = 0; y < h; y += 4) |
| 235 | { | ||
| 236 | 8 | BYTE* d0 = dstp + y * 4; | |
| 237 |
2/2✓ Branch 34 → 4 taken 16 times.
✓ Branch 34 → 35 taken 8 times.
|
24 | for (int x = 0; x < w; x += 16) |
| 238 | { | ||
| 239 | 16 | transpose_32x4x4_sse2(s0 + x, d0, -src_pitch, dst_pitch); | |
| 240 | 16 | d0 += 4 * dst_pitch; | |
| 241 | } | ||
| 242 | 8 | s0 -= 4 * src_pitch; | |
| 243 | } | ||
| 244 | |||
| 245 |
1/2✓ Branch 37 → 38 taken 4 times.
✗ Branch 37 → 39 not taken.
|
4 | if (src_rowsize != w) |
| 246 | { | ||
| 247 | 4 | turn_right_plane_32_c(srcp + w, dstp + w / 4 * dst_pitch, src_rowsize - w, src_height, src_pitch, dst_pitch); | |
| 248 | } | ||
| 249 | |||
| 250 |
1/2✓ Branch 39 → 40 taken 4 times.
✗ Branch 39 → 41 not taken.
|
4 | if (src_height != h) |
| 251 | { | ||
| 252 | 4 | turn_right_plane_32_c(srcp, dstp + h * 4, src_rowsize, src_height - h, src_pitch, dst_pitch); | |
| 253 | } | ||
| 254 | 4 | } | |
| 255 | |||
| 256 | 2 | void turn_left_plane_32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 257 | { | ||
| 258 | 2 | turn_right_plane_32_sse2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 4 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch); | |
| 259 | 2 | } | |
| 260 | |||
| 261 | |||
| 262 | // on RGB, TurnLeft and TurnRight are reversed. | ||
| 263 | |||
| 264 | 1 | void turn_left_rgb32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 265 | { | ||
| 266 | 1 | turn_right_plane_32_sse2(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch); | |
| 267 | 1 | } | |
| 268 | |||
| 269 | |||
| 270 | 1 | void turn_right_rgb32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 271 | { | ||
| 272 | 1 | turn_left_plane_32_sse2(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch); | |
| 273 | 1 | } | |
| 274 | |||
| 275 | |||
| 276 | |||
| 277 | |||
| 278 | 2 | static inline void turn_right_plane_64_sse2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 279 | { | ||
| 280 | 2 | const BYTE* s0 = srcp + src_pitch * (src_height - 1); | |
| 281 | 2 | int w = src_rowsize & ~15; | |
| 282 | 2 | int h = src_height & ~1; | |
| 283 | |||
| 284 |
2/2✓ Branch 17 → 3 taken 6 times.
✓ Branch 17 → 18 taken 2 times.
|
8 | for (int y = 0; y < h; y += 2) |
| 285 | { | ||
| 286 | 6 | BYTE* d0 = dstp + y * 8; | |
| 287 |
2/2✓ Branch 15 → 4 taken 12 times.
✓ Branch 15 → 16 taken 6 times.
|
18 | for (int x = 0; x < w; x += 16) |
| 288 | { | ||
| 289 | 12 | __m128i a01 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(s0 + x)); // a0 a1 | |
| 290 | 24 | __m128i b01 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(s0 + x - src_pitch)); // b0 b1 | |
| 291 | 12 | __m128i ab0 = _mm_unpacklo_epi64(a01, b01); // a0 b0 | |
| 292 | 12 | __m128i ab1 = _mm_unpackhi_epi64(a01, b01); // a1 b1 | |
| 293 | _mm_storeu_si128(reinterpret_cast<__m128i*>(d0), ab0); | ||
| 294 | 12 | _mm_storeu_si128(reinterpret_cast<__m128i*>(d0 + dst_pitch), ab1); | |
| 295 | 12 | d0 += 2 * dst_pitch; | |
| 296 | } | ||
| 297 | 6 | s0 -= 2 * src_pitch; | |
| 298 | } | ||
| 299 | |||
| 300 |
1/2✓ Branch 18 → 19 taken 2 times.
✗ Branch 18 → 20 not taken.
|
2 | if (src_rowsize != w) |
| 301 | { | ||
| 302 | 2 | turn_right_plane_c<uint64_t>(srcp + w, dstp + w / 8 * dst_pitch, 8, src_height, src_pitch, dst_pitch); | |
| 303 | } | ||
| 304 | |||
| 305 |
1/2✓ Branch 20 → 21 taken 2 times.
✗ Branch 20 → 22 not taken.
|
2 | if (src_height != h) |
| 306 | { | ||
| 307 | 2 | turn_right_plane_c<uint64_t>(srcp, dstp + h * 8, src_rowsize, 1, src_pitch, dst_pitch); | |
| 308 | } | ||
| 309 | 2 | } | |
| 310 | |||
| 311 | |||
| 312 | 1 | void turn_left_rgb64_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 313 | { | ||
| 314 | 1 | turn_right_plane_64_sse2(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch); | |
| 315 | 1 | } | |
| 316 | |||
| 317 | |||
| 318 | 1 | void turn_right_rgb64_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 319 | { | ||
| 320 | 1 | turn_right_plane_64_sse2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 8 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch); | |
| 321 | 1 | } | |
| 322 | |||
| 323 | |||
| 324 | |||
| 325 | |||
| 326 | |||
| 327 | template <typename T> | ||
| 328 | 4 | void turn_180_plane_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 329 | { | ||
| 330 | 4 | const BYTE* AVS_RESTRICT s0 = srcp; | |
| 331 | 4 | BYTE* AVS_RESTRICT d0 = dstp + dst_pitch * (src_height - 1) + src_rowsize - 16; | |
| 332 | 4 | const int w = src_rowsize & ~15; | |
| 333 | |||
| 334 |
8/8void turn_180_plane_sse2<unsigned char>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 16 → 3 taken 9 times.
✓ Branch 16 → 17 taken 1 time.
void turn_180_plane_sse2<unsigned int>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 10 → 3 taken 7 times.
✓ Branch 10 → 11 taken 1 time.
void turn_180_plane_sse2<unsigned long>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 10 → 3 taken 7 times.
✓ Branch 10 → 11 taken 1 time.
void turn_180_plane_sse2<unsigned short>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 10 → 3 taken 7 times.
✓ Branch 10 → 11 taken 1 time.
|
34 | for (int y = 0; y < src_height; ++y) |
| 335 | { | ||
| 336 |
8/8void turn_180_plane_sse2<unsigned char>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 14 → 4 taken 18 times.
✓ Branch 14 → 15 taken 9 times.
void turn_180_plane_sse2<unsigned int>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 8 → 4 taken 14 times.
✓ Branch 8 → 9 taken 7 times.
void turn_180_plane_sse2<unsigned long>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 8 → 4 taken 14 times.
✓ Branch 8 → 9 taken 7 times.
void turn_180_plane_sse2<unsigned short>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 8 → 4 taken 14 times.
✓ Branch 8 → 9 taken 7 times.
|
90 | for (int x = 0; x < w; x += 16) |
| 337 | { | ||
| 338 | 60 | __m128i src = _mm_loadu_si128(reinterpret_cast<const __m128i*>(s0 + x)); | |
| 339 | if constexpr (sizeof(T) == 8) // RGB64 | ||
| 340 | 14 | src = _mm_shuffle_epi32(src, _MM_SHUFFLE(1, 0, 3, 2)); | |
| 341 | else if constexpr (sizeof(T) == 4) // RGB32 | ||
| 342 | 14 | src = _mm_shuffle_epi32(src, _MM_SHUFFLE(0, 1, 2, 3)); | |
| 343 | else { // uint16_t, uint8_t | ||
| 344 | 32 | src = _mm_shuffle_epi32(src, _MM_SHUFFLE(0, 1, 2, 3)); | |
| 345 | 32 | src = _mm_shufflelo_epi16(src, _MM_SHUFFLE(2, 3, 0, 1)); | |
| 346 | 32 | src = _mm_shufflehi_epi16(src, _MM_SHUFFLE(2, 3, 0, 1)); | |
| 347 | |||
| 348 | if constexpr (sizeof(T) == 1) | ||
| 349 | 36 | src = _mm_or_si128(_mm_srli_epi16(src, 8), _mm_slli_epi16(src, 8)); | |
| 350 | } | ||
| 351 | 60 | _mm_storeu_si128(reinterpret_cast<__m128i*>(d0 - x), src); | |
| 352 | } | ||
| 353 | 30 | s0 += src_pitch; | |
| 354 | 30 | d0 -= dst_pitch; | |
| 355 | } | ||
| 356 | |||
| 357 |
4/8void turn_180_plane_sse2<unsigned char>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 19 not taken.
void turn_180_plane_sse2<unsigned int>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 13 not taken.
void turn_180_plane_sse2<unsigned long>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 13 not taken.
void turn_180_plane_sse2<unsigned short>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 11 → 12 taken 1 time.
✗ Branch 11 → 13 not taken.
|
4 | if (src_rowsize != w) |
| 358 | { | ||
| 359 | 4 | turn_180_plane_c<T>(srcp + w, dstp, src_rowsize - w, src_height, src_pitch, dst_pitch); | |
| 360 | } | ||
| 361 | 4 | } | |
| 362 | |||
| 363 | // instantiate | ||
| 364 | template void turn_180_plane_sse2<uint8_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch); | ||
| 365 | template void turn_180_plane_sse2<uint16_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch); | ||
| 366 | template void turn_180_plane_sse2<uint32_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch); | ||
| 367 | template void turn_180_plane_sse2<uint64_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch); | ||
| 368 | |||
| 369 | |||
| 370 | template <typename T> | ||
| 371 | #if defined(GCC) || defined(CLANG) | ||
| 372 | __attribute__((__target__("ssse3"))) | ||
| 373 | #endif | ||
| 374 | 2 | void turn_180_plane_ssse3(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch) | |
| 375 | { | ||
| 376 | 2 | const BYTE* s0 = srcp; | |
| 377 | 2 | BYTE* d0 = dstp + dst_pitch * (src_height - 1) + src_rowsize - 16; | |
| 378 | 2 | const int w = src_rowsize & ~15; | |
| 379 | |||
| 380 |
4/4void turn_180_plane_ssse3<unsigned char>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 14 → 3 taken 9 times.
✓ Branch 14 → 15 taken 1 time.
void turn_180_plane_ssse3<unsigned short>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 14 → 3 taken 7 times.
✓ Branch 14 → 15 taken 1 time.
|
18 | for (int y = 0; y < src_height; ++y) |
| 381 | { | ||
| 382 |
4/4void turn_180_plane_ssse3<unsigned char>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 12 → 4 taken 18 times.
✓ Branch 12 → 13 taken 9 times.
void turn_180_plane_ssse3<unsigned short>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 12 → 4 taken 14 times.
✓ Branch 12 → 13 taken 7 times.
|
48 | for (int x = 0; x < w; x += 16) |
| 383 | { | ||
| 384 | 64 | __m128i src = _mm_loadu_si128(reinterpret_cast<const __m128i*>(s0 + x)); | |
| 385 | if constexpr (sizeof(T) == 8) // RGB64 | ||
| 386 | src = _mm_shuffle_epi32(src, _MM_SHUFFLE(1, 0, 3, 2)); | ||
| 387 | else if constexpr (sizeof(T) == 4) // RGB32 | ||
| 388 | src = _mm_shuffle_epi32(src, _MM_SHUFFLE(0, 1, 2, 3)); | ||
| 389 | else { // uint16_t, uint8_t | ||
| 390 | // SSSE3 | ||
| 391 | __m128i pshufb_mask; | ||
| 392 | if constexpr (sizeof(T) == 1) | ||
| 393 | 18 | pshufb_mask = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); | |
| 394 | else if constexpr (sizeof(T) == 2) | ||
| 395 | 14 | pshufb_mask = _mm_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14); | |
| 396 | |||
| 397 | 32 | src = _mm_shuffle_epi8(src, pshufb_mask); | |
| 398 | } | ||
| 399 | 32 | _mm_storeu_si128(reinterpret_cast<__m128i*>(d0 - x), src); | |
| 400 | } | ||
| 401 | 16 | s0 += src_pitch; | |
| 402 | 16 | d0 -= dst_pitch; | |
| 403 | } | ||
| 404 | |||
| 405 |
2/4void turn_180_plane_ssse3<unsigned char>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 17 not taken.
void turn_180_plane_ssse3<unsigned short>(unsigned char const*, unsigned char*, int, int, int, int):
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 17 not taken.
|
2 | if (src_rowsize != w) |
| 406 | { | ||
| 407 | 2 | turn_180_plane_c<T>(srcp + w, dstp, src_rowsize - w, src_height, src_pitch, dst_pitch); | |
| 408 | } | ||
| 409 | 2 | } | |
| 410 | |||
| 411 | // instantiate | ||
| 412 | template void turn_180_plane_ssse3<uint8_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch); | ||
| 413 | template void turn_180_plane_ssse3<uint16_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch); | ||
| 414 |