Cycles Denoising: Merge outlier heuristic and confidence interval test
[blender.git] / intern / cycles / kernel / kernels / cpu / filter_cpu_impl.h
1 /*
2  * Copyright 2011-2017 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* Templated common implementation part of all CPU kernels.
18  *
19  * The idea is that particular .cpp files sets needed optimization flags and
20  * simply includes this file without worry of copying actual implementation over.
21  */
22
23 #include "kernel/kernel_compat_cpu.h"
24
25 #include "kernel/filter/filter_kernel.h"
26
27 #ifdef KERNEL_STUB
28 #  include "util/util_debug.h"
29 #  define STUB_ASSERT(arch, name) assert(!(#name " kernel stub for architecture " #arch " was called!"))
30 #endif
31
32 CCL_NAMESPACE_BEGIN
33
34
35 /* Denoise filter */
36
37 void KERNEL_FUNCTION_FULL_NAME(filter_divide_shadow)(int sample,
38                                                      TilesInfo *tiles,
39                                                      int x,
40                                                      int y,
41                                                      float *unfilteredA,
42                                                      float *unfilteredB,
43                                                      float *sampleVariance,
44                                                      float *sampleVarianceV,
45                                                      float *bufferVariance,
46                                                      int* prefilter_rect,
47                                                      int buffer_pass_stride,
48                                                      int buffer_denoising_offset,
49                                                      bool use_split_variance)
50 {
51 #ifdef KERNEL_STUB
52         STUB_ASSERT(KERNEL_ARCH, filter_divide_shadow);
53 #else
54         kernel_filter_divide_shadow(sample, tiles,
55                                     x, y,
56                                     unfilteredA,
57                                     unfilteredB,
58                                     sampleVariance,
59                                     sampleVarianceV,
60                                     bufferVariance,
61                                     load_int4(prefilter_rect),
62                                     buffer_pass_stride,
63                                     buffer_denoising_offset,
64                                     use_split_variance);
65 #endif
66 }
67
68 void KERNEL_FUNCTION_FULL_NAME(filter_get_feature)(int sample,
69                                                    TilesInfo *tiles,
70                                                    int m_offset,
71                                                    int v_offset,
72                                                    int x,
73                                                    int y,
74                                                    float *mean, float *variance,
75                                                    int* prefilter_rect,
76                                                    int buffer_pass_stride,
77                                                    int buffer_denoising_offset,
78                                                    bool use_split_variance)
79 {
80 #ifdef KERNEL_STUB
81         STUB_ASSERT(KERNEL_ARCH, filter_get_feature);
82 #else
83         kernel_filter_get_feature(sample, tiles,
84                                   m_offset, v_offset,
85                                   x, y,
86                                   mean, variance,
87                                   load_int4(prefilter_rect),
88                                   buffer_pass_stride,
89                                   buffer_denoising_offset,
90                                   use_split_variance);
91 #endif
92 }
93
94 void KERNEL_FUNCTION_FULL_NAME(filter_detect_outliers)(int x, int y,
95                                                        ccl_global float *image,
96                                                        ccl_global float *variance,
97                                                        ccl_global float *depth,
98                                                        ccl_global float *output,
99                                                        int *rect,
100                                                        int pass_stride)
101 {
102 #ifdef KERNEL_STUB
103         STUB_ASSERT(KERNEL_ARCH, filter_detect_outliers);
104 #else
105         kernel_filter_detect_outliers(x, y, image, variance, depth, output, load_int4(rect), pass_stride);
106 #endif
107 }
108
109 void KERNEL_FUNCTION_FULL_NAME(filter_combine_halves)(int x, int y,
110                                                       float *mean,
111                                                       float *variance,
112                                                       float *a,
113                                                       float *b,
114                                                       int* prefilter_rect,
115                                                       int r)
116 {
117 #ifdef KERNEL_STUB
118         STUB_ASSERT(KERNEL_ARCH, filter_combine_halves);
119 #else
120         kernel_filter_combine_halves(x, y, mean, variance, a, b, load_int4(prefilter_rect), r);
121 #endif
122 }
123
124 void KERNEL_FUNCTION_FULL_NAME(filter_construct_transform)(float* buffer,
125                                                            int x,
126                                                            int y,
127                                                            int storage_ofs,
128                                                            float *transform,
129                                                            int *rank,
130                                                            int* prefilter_rect,
131                                                            int pass_stride,
132                                                            int radius,
133                                                            float pca_threshold)
134 {
135 #ifdef KERNEL_STUB
136         STUB_ASSERT(KERNEL_ARCH, filter_construct_transform);
137 #else
138   rank += storage_ofs;
139   transform += storage_ofs*TRANSFORM_SIZE;
140         kernel_filter_construct_transform(buffer,
141                                           x, y,
142                                           load_int4(prefilter_rect),
143                                           pass_stride,
144                                           transform,
145                                           rank,
146                                           radius,
147                                           pca_threshold);
148 #endif
149 }
150
151 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_difference)(int dx,
152                                                            int dy,
153                                                            float *weight_image,
154                                                            float *variance,
155                                                            float *difference_image,
156                                                            int *rect,
157                                                            int w,
158                                                            int channel_offset,
159                                                            float a,
160                                                            float k_2)
161 {
162 #ifdef KERNEL_STUB
163         STUB_ASSERT(KERNEL_ARCH, filter_nlm_calc_difference);
164 #else
165         kernel_filter_nlm_calc_difference(dx, dy, weight_image, variance, difference_image, load_int4(rect), w, channel_offset, a, k_2);
166 #endif
167 }
168
169 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_blur)(float *difference_image,
170                                                 float *out_image,
171                                                 int *rect,
172                                                 int w,
173                                                 int f)
174 {
175 #ifdef KERNEL_STUB
176         STUB_ASSERT(KERNEL_ARCH, filter_nlm_blur);
177 #else
178         kernel_filter_nlm_blur(difference_image, out_image, load_int4(rect), w, f);
179 #endif
180 }
181
182 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_weight)(float *difference_image,
183                                                        float *out_image,
184                                                        int *rect,
185                                                        int w,
186                                                        int f)
187 {
188 #ifdef KERNEL_STUB
189         STUB_ASSERT(KERNEL_ARCH, filter_nlm_calc_weight);
190 #else
191         kernel_filter_nlm_calc_weight(difference_image, out_image, load_int4(rect), w, f);
192 #endif
193 }
194
195 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_update_output)(int dx,
196                                                          int dy,
197                                                          float *difference_image,
198                                                          float *image,
199                                                          float *out_image,
200                                                          float *accum_image,
201                                                          int *rect,
202                                                          int w,
203                                                          int f)
204 {
205 #ifdef KERNEL_STUB
206         STUB_ASSERT(KERNEL_ARCH, filter_nlm_update_output);
207 #else
208         kernel_filter_nlm_update_output(dx, dy, difference_image, image, out_image, accum_image, load_int4(rect), w, f);
209 #endif
210 }
211
212 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_construct_gramian)(int dx,
213                                                              int dy,
214                                                              float *difference_image,
215                                                              float *buffer,
216                                                              float *transform,
217                                                              int *rank,
218                                                              float *XtWX,
219                                                              float3 *XtWY,
220                                                              int *rect,
221                                                              int *filter_rect,
222                                                              int w,
223                                                              int h,
224                                                              int f,
225                                                              int pass_stride)
226 {
227 #ifdef KERNEL_STUB
228         STUB_ASSERT(KERNEL_ARCH, filter_nlm_construct_gramian);
229 #else
230     kernel_filter_nlm_construct_gramian(dx, dy, difference_image, buffer, transform, rank, XtWX, XtWY, load_int4(rect), load_int4(filter_rect), w, h, f, pass_stride);
231 #endif
232 }
233
234 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_normalize)(float *out_image,
235                                                      float *accum_image,
236                                                      int *rect,
237                                                      int w)
238 {
239 #ifdef KERNEL_STUB
240         STUB_ASSERT(KERNEL_ARCH, filter_nlm_normalize);
241 #else
242         kernel_filter_nlm_normalize(out_image, accum_image, load_int4(rect), w);
243 #endif
244 }
245
246 void KERNEL_FUNCTION_FULL_NAME(filter_finalize)(int x,
247                                                 int y,
248                                                 int storage_ofs,
249                                                 int w,
250                                                 int h,
251                                                 float *buffer,
252                                                 int *rank,
253                                                 float *XtWX,
254                                                 float3 *XtWY,
255                                                 int *buffer_params,
256                                                 int sample)
257 {
258 #ifdef KERNEL_STUB
259         STUB_ASSERT(KERNEL_ARCH, filter_finalize);
260 #else
261         XtWX += storage_ofs*XTWX_SIZE;
262         XtWY += storage_ofs*XTWY_SIZE;
263         rank += storage_ofs;
264         kernel_filter_finalize(x, y, w, h, buffer, rank, 1, XtWX, XtWY, load_int4(buffer_params), sample);
265 #endif
266 }
267
268 #undef KERNEL_STUB
269 #undef STUB_ASSERT
270 #undef KERNEL_ARCH
271
272 CCL_NAMESPACE_END