Cycles: Implement denoising option for reducing noise in the rendered image
[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_combine_halves)(int x, int y,
95                                                       float *mean,
96                                                       float *variance,
97                                                       float *a,
98                                                       float *b,
99                                                       int* prefilter_rect,
100                                                       int r)
101 {
102 #ifdef KERNEL_STUB
103         STUB_ASSERT(KERNEL_ARCH, filter_combine_halves);
104 #else
105         kernel_filter_combine_halves(x, y, mean, variance, a, b, load_int4(prefilter_rect), r);
106 #endif
107 }
108
109 void KERNEL_FUNCTION_FULL_NAME(filter_construct_transform)(float* buffer,
110                                                            int x,
111                                                            int y,
112                                                            int storage_ofs,
113                                                            float *transform,
114                                                            int *rank,
115                                                            int* prefilter_rect,
116                                                            int pass_stride,
117                                                            int radius,
118                                                            float pca_threshold)
119 {
120 #ifdef KERNEL_STUB
121         STUB_ASSERT(KERNEL_ARCH, filter_construct_transform);
122 #else
123   rank += storage_ofs;
124   transform += storage_ofs*TRANSFORM_SIZE;
125         kernel_filter_construct_transform(buffer,
126                                           x, y,
127                                           load_int4(prefilter_rect),
128                                           pass_stride,
129                                           transform,
130                                           rank,
131                                           radius,
132                                           pca_threshold);
133 #endif
134 }
135
136 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_difference)(int dx,
137                                                            int dy,
138                                                            float *weightImage,
139                                                            float *variance,
140                                                            float *differenceImage,
141                                                            int *rect,
142                                                            int w,
143                                                            int channel_offset,
144                                                            float a,
145                                                            float k_2)
146 {
147 #ifdef KERNEL_STUB
148         STUB_ASSERT(KERNEL_ARCH, filter_nlm_calc_difference);
149 #else
150         kernel_filter_nlm_calc_difference(dx, dy, weightImage, variance, differenceImage, load_int4(rect), w, channel_offset, a, k_2);
151 #endif
152 }
153
154 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_blur)(float *differenceImage,
155                                                 float *outImage,
156                                                 int *rect,
157                                                 int w,
158                                                 int f)
159 {
160 #ifdef KERNEL_STUB
161         STUB_ASSERT(KERNEL_ARCH, filter_nlm_blur);
162 #else
163         kernel_filter_nlm_blur(differenceImage, outImage, load_int4(rect), w, f);
164 #endif
165 }
166
167 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_calc_weight)(float *differenceImage,
168                                                        float *outImage,
169                                                        int *rect,
170                                                        int w,
171                                                        int f)
172 {
173 #ifdef KERNEL_STUB
174         STUB_ASSERT(KERNEL_ARCH, filter_nlm_calc_weight);
175 #else
176         kernel_filter_nlm_calc_weight(differenceImage, outImage, load_int4(rect), w, f);
177 #endif
178 }
179
180 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_update_output)(int dx,
181                                                          int dy,
182                                                          float *differenceImage,
183                                                          float *image,
184                                                          float *outImage,
185                                                          float *accumImage,
186                                                          int *rect,
187                                                          int w,
188                                                          int f)
189 {
190 #ifdef KERNEL_STUB
191         STUB_ASSERT(KERNEL_ARCH, filter_nlm_update_output);
192 #else
193         kernel_filter_nlm_update_output(dx, dy, differenceImage, image, outImage, accumImage, load_int4(rect), w, f);
194 #endif
195 }
196
197 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_construct_gramian)(int dx,
198                                                              int dy,
199                                                              float *differenceImage,
200                                                              float *buffer,
201                                                              float *color_pass,
202                                                              float *variance_pass,
203                                                              float *transform,
204                                                              int *rank,
205                                                              float *XtWX,
206                                                              float3 *XtWY,
207                                                              int *rect,
208                                                              int *filter_rect,
209                                                              int w,
210                                                              int h,
211                                                              int f,
212                                                              int pass_stride)
213 {
214 #ifdef KERNEL_STUB
215         STUB_ASSERT(KERNEL_ARCH, filter_nlm_construct_gramian);
216 #else
217     kernel_filter_nlm_construct_gramian(dx, dy, differenceImage, buffer, color_pass, variance_pass, transform, rank, XtWX, XtWY, load_int4(rect), load_int4(filter_rect), w, h, f, pass_stride);
218 #endif
219 }
220
221 void KERNEL_FUNCTION_FULL_NAME(filter_nlm_normalize)(float *outImage,
222                                                      float *accumImage,
223                                                      int *rect,
224                                                      int w)
225 {
226 #ifdef KERNEL_STUB
227         STUB_ASSERT(KERNEL_ARCH, filter_nlm_normalize);
228 #else
229         kernel_filter_nlm_normalize(outImage, accumImage, load_int4(rect), w);
230 #endif
231 }
232
233 void KERNEL_FUNCTION_FULL_NAME(filter_finalize)(int x,
234                                                 int y,
235                                                 int storage_ofs,
236                                                 int w,
237                                                 int h,
238                                                 float *buffer,
239                                                 int *rank,
240                                                 float *XtWX,
241                                                 float3 *XtWY,
242                                                 int *buffer_params,
243                                                 int sample)
244 {
245 #ifdef KERNEL_STUB
246         STUB_ASSERT(KERNEL_ARCH, filter_finalize);
247 #else
248         XtWX += storage_ofs*XTWX_SIZE;
249         XtWY += storage_ofs*XTWY_SIZE;
250         rank += storage_ofs;
251         kernel_filter_finalize(x, y, w, h, buffer, rank, 1, XtWX, XtWY, load_int4(buffer_params), sample);
252 #endif
253 }
254
255 #undef KERNEL_STUB
256 #undef STUB_ASSERT
257 #undef KERNEL_ARCH
258
259 CCL_NAMESPACE_END