GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 17 / 0 / 17
Functions: 100.0% 1 / 0 / 1
Branches: 100.0% 6 / 0 / 6

filters/conditional/intel/conditional_functions_sse.cpp
Line Branch Exec Source
1
2 // Avisynth v2.5. Copyright 2002 Ben Rudiak-Gould et al.
3 // http://avisynth.nl
4
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
18 // http://www.gnu.org/copyleft/gpl.html .
19 //
20 // Linking Avisynth statically or dynamically with other modules is making a
21 // combined work based on Avisynth. Thus, the terms and conditions of the GNU
22 // General Public License cover the whole combination.
23 //
24 // As a special exception, the copyright holders of Avisynth give you
25 // permission to link Avisynth with independent modules that communicate with
26 // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
27 // terms of these independent modules, and to copy and distribute the
28 // resulting combined work under terms of your choice, provided that
29 // every copy of the combined work is accompanied by a complete copy of
30 // the source code of Avisynth (the version of Avisynth used to produce the
31 // combined work), being distributed under the terms of the GNU General
32 // Public License plus this exception. An independent module is a module
33 // which is not derived from or based on Avisynth, such as 3rd-party filters,
34 // import and export plugins, or graphical user interfaces.
35
36 #include <avisynth.h>
37 #include <cstdint>
38
39 // Intrinsics base header + really required extension headers
40 #if defined(_MSC_VER)
41 #include <intrin.h> // MSVC
42 #else
43 #include <x86intrin.h> // GCC/MinGW/Clang/LLVM
44 #endif
45
46 #include <algorithm>
47
48 // sum: sad with zero
49 2 double get_sum_of_pixels_sse2(const uint8_t* srcp, size_t height, size_t width, size_t pitch) {
50 2 size_t mod16_width = width / 16 * 16;
51 2 int64_t result = 0;
52 2 __m128i sum = _mm_setzero_si128();
53 2 __m128i zero = _mm_setzero_si128();
54
55
2/2
✓ Branch 20 → 7 taken 12 times.
✓ Branch 20 → 21 taken 2 times.
14 for (size_t y = 0; y < height; ++y) {
56
2/2
✓ Branch 15 → 8 taken 31 times.
✓ Branch 15 → 16 taken 12 times.
43 for (size_t x = 0; x < mod16_width; x+=16) {
57 62 __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));
58 31 __m128i sad = _mm_sad_epu8(src, zero);
59 31 sum = _mm_add_epi32(sum, sad);
60 }
61
62
2/2
✓ Branch 18 → 17 taken 60 times.
✓ Branch 18 → 19 taken 12 times.
72 for (size_t x = mod16_width; x < width; ++x) {
63 60 result += srcp[x];
64 }
65
66 12 srcp += pitch;
67 }
68 8 __m128i upper = _mm_castps_si128(_mm_movehl_ps(_mm_setzero_ps(), _mm_castsi128_ps(sum)));
69 2 sum = _mm_add_epi32(sum, upper);
70 2 result += _mm_cvtsi128_si32(sum);
71 2 return (double)result;
72 }
73
74 #ifdef X86_32
75 double get_sum_of_pixels_isse(const uint8_t* srcp, size_t height, size_t width, size_t pitch) {
76 size_t mod8_width = width / 8 * 8;
77 int64_t result = 0;
78 __m64 sum = _mm_setzero_si64();
79 __m64 zero = _mm_setzero_si64();
80
81 for (size_t y = 0; y < height; ++y) {
82 for (size_t x = 0; x < mod8_width; x+=8) {
83 __m64 src = *reinterpret_cast<const __m64*>(srcp + x);
84 __m64 sad = _mm_sad_pu8(src, zero);
85 sum = _mm_add_pi32(sum, sad);
86 }
87
88 for (size_t x = mod8_width; x < width; ++x) {
89 result += srcp[x];
90 }
91
92 srcp += pitch;
93 }
94 result += _mm_cvtsi64_si32(sum);
95 _mm_empty();
96 return (double)result;
97 }
98
99 size_t get_sad_isse(const uint8_t* src_ptr, const uint8_t* other_ptr, size_t height, size_t width, size_t src_pitch, size_t other_pitch) {
100 size_t mod8_width = width / 8 * 8;
101 size_t result = 0;
102 __m64 sum = _mm_setzero_si64();
103
104 for (size_t y = 0; y < height; ++y) {
105 for (size_t x = 0; x < mod8_width; x+=8) {
106 __m64 src = *reinterpret_cast<const __m64*>(src_ptr + x);
107 __m64 other = *reinterpret_cast<const __m64*>(other_ptr + x);
108 __m64 sad = _mm_sad_pu8(src, other);
109 sum = _mm_add_pi32(sum, sad);
110 }
111
112 for (size_t x = mod8_width; x < width; ++x) {
113 result += std::abs(src_ptr[x] - other_ptr[x]);
114 }
115
116 src_ptr += src_pitch;
117 other_ptr += other_pitch;
118 }
119 result += _mm_cvtsi64_si32(sum);
120 _mm_empty();
121 return result;
122 }
123
124 size_t get_sad_rgb_isse(const uint8_t* src_ptr, const uint8_t* other_ptr, size_t height, size_t width, size_t src_pitch, size_t other_pitch) {
125 size_t mod8_width = width / 8 * 8;
126 size_t result = 0;
127 __m64 rgb_mask = _mm_set1_pi32(0x00FFFFFF);
128 __m64 sum = _mm_setzero_si64();
129
130 for (size_t y = 0; y < height; ++y) {
131 for (size_t x = 0; x < mod8_width; x+=8) {
132 __m64 src = *reinterpret_cast<const __m64*>(src_ptr + x);
133 __m64 other = *reinterpret_cast<const __m64*>(other_ptr + x);
134 src = _mm_and_si64(src, rgb_mask);
135 other = _mm_and_si64(other, rgb_mask);
136 __m64 sad = _mm_sad_pu8(src, other);
137 sum = _mm_add_pi32(sum, sad);
138 }
139
140 for (size_t x = mod8_width; x < width; ++x) {
141 result += std::abs(src_ptr[x] - other_ptr[x]);
142 }
143
144 src_ptr += src_pitch;
145 other_ptr += other_pitch;
146 }
147 result += _mm_cvtsi64_si32(sum);
148 _mm_empty();
149 return result;
150 }
151
152 #endif
153
154