Fix T53410: 3D Text always recalculated
[blender.git] / intern / cycles / device / device_denoising.cpp
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 #include "device/device_denoising.h"
18
19 #include "kernel/filter/filter_defines.h"
20
21 CCL_NAMESPACE_BEGIN
22
23 DenoisingTask::DenoisingTask(Device *device)
24 : tiles_mem(device, "denoising tiles_mem", MEM_READ_WRITE),
25   storage(device),
26   buffer(device),
27   device(device)
28 {
29 }
30
31 DenoisingTask::~DenoisingTask()
32 {
33         storage.XtWX.free();
34         storage.XtWY.free();
35         storage.transform.free();
36         storage.rank.free();
37         storage.temporary_1.free();
38         storage.temporary_2.free();
39         storage.temporary_color.free();
40         buffer.mem.free();
41         tiles_mem.free();
42 }
43
44 void DenoisingTask::init_from_devicetask(const DeviceTask &task)
45 {
46         radius = task.denoising_radius;
47         nlm_k_2 = powf(2.0f, lerp(-5.0f, 3.0f, task.denoising_strength));
48         if(task.denoising_relative_pca) {
49                 pca_threshold = -powf(10.0f, lerp(-8.0f, 0.0f, task.denoising_feature_strength));
50         }
51         else {
52                 pca_threshold = powf(10.0f, lerp(-5.0f, 3.0f, task.denoising_feature_strength));
53         }
54
55         render_buffer.pass_stride = task.pass_stride;
56         render_buffer.denoising_data_offset  = task.pass_denoising_data;
57         render_buffer.denoising_clean_offset = task.pass_denoising_clean;
58
59         /* Expand filter_area by radius pixels and clamp the result to the extent of the neighboring tiles */
60         rect = make_int4(max(tiles->x[0], filter_area.x - radius),
61                          max(tiles->y[0], filter_area.y - radius),
62                          min(tiles->x[3], filter_area.x + filter_area.z + radius),
63                          min(tiles->y[3], filter_area.y + filter_area.w + radius));
64 }
65
66 void DenoisingTask::tiles_from_rendertiles(RenderTile *rtiles)
67 {
68         tiles = (TilesInfo*) tiles_mem.alloc(sizeof(TilesInfo)/sizeof(int));
69
70         device_ptr buffers[9];
71         for(int i = 0; i < 9; i++) {
72                 buffers[i] = rtiles[i].buffer;
73                 tiles->offsets[i] = rtiles[i].offset;
74                 tiles->strides[i] = rtiles[i].stride;
75         }
76         tiles->x[0] = rtiles[3].x;
77         tiles->x[1] = rtiles[4].x;
78         tiles->x[2] = rtiles[5].x;
79         tiles->x[3] = rtiles[5].x + rtiles[5].w;
80         tiles->y[0] = rtiles[1].y;
81         tiles->y[1] = rtiles[4].y;
82         tiles->y[2] = rtiles[7].y;
83         tiles->y[3] = rtiles[7].y + rtiles[7].h;
84
85         render_buffer.offset = rtiles[4].offset;
86         render_buffer.stride = rtiles[4].stride;
87         render_buffer.ptr    = rtiles[4].buffer;
88
89         functions.set_tiles(buffers);
90 }
91
92 bool DenoisingTask::run_denoising()
93 {
94         /* Allocate denoising buffer. */
95         buffer.passes = 14;
96         buffer.w = align_up(rect.z - rect.x, 4);
97         buffer.h = rect.w - rect.y;
98         buffer.pass_stride = align_up(buffer.w * buffer.h, divide_up(device->mem_address_alignment(), sizeof(float)));
99         buffer.mem.alloc_to_device(buffer.pass_stride * buffer.passes, false);
100
101         device_ptr null_ptr = (device_ptr) 0;
102
103         /* Prefilter shadow feature. */
104         {
105                 device_sub_ptr unfiltered_a   (buffer.mem, 0,                    buffer.pass_stride);
106                 device_sub_ptr unfiltered_b   (buffer.mem, 1*buffer.pass_stride, buffer.pass_stride);
107                 device_sub_ptr sample_var     (buffer.mem, 2*buffer.pass_stride, buffer.pass_stride);
108                 device_sub_ptr sample_var_var (buffer.mem, 3*buffer.pass_stride, buffer.pass_stride);
109                 device_sub_ptr buffer_var     (buffer.mem, 5*buffer.pass_stride, buffer.pass_stride);
110                 device_sub_ptr filtered_var   (buffer.mem, 6*buffer.pass_stride, buffer.pass_stride);
111                 device_sub_ptr nlm_temporary_1(buffer.mem, 7*buffer.pass_stride, buffer.pass_stride);
112                 device_sub_ptr nlm_temporary_2(buffer.mem, 8*buffer.pass_stride, buffer.pass_stride);
113                 device_sub_ptr nlm_temporary_3(buffer.mem, 9*buffer.pass_stride, buffer.pass_stride);
114
115                 nlm_state.temporary_1_ptr = *nlm_temporary_1;
116                 nlm_state.temporary_2_ptr = *nlm_temporary_2;
117                 nlm_state.temporary_3_ptr = *nlm_temporary_3;
118
119                 /* Get the A/B unfiltered passes, the combined sample variance, the estimated variance of the sample variance and the buffer variance. */
120                 functions.divide_shadow(*unfiltered_a, *unfiltered_b, *sample_var, *sample_var_var, *buffer_var);
121
122                 /* Smooth the (generally pretty noisy) buffer variance using the spatial information from the sample variance. */
123                 nlm_state.set_parameters(6, 3, 4.0f, 1.0f);
124                 functions.non_local_means(*buffer_var, *sample_var, *sample_var_var, *filtered_var);
125
126                 /* Reuse memory, the previous data isn't needed anymore. */
127                 device_ptr filtered_a = *buffer_var,
128                            filtered_b = *sample_var;
129                 /* Use the smoothed variance to filter the two shadow half images using each other for weight calculation. */
130                 nlm_state.set_parameters(5, 3, 1.0f, 0.25f);
131                 functions.non_local_means(*unfiltered_a, *unfiltered_b, *filtered_var, filtered_a);
132                 functions.non_local_means(*unfiltered_b, *unfiltered_a, *filtered_var, filtered_b);
133
134                 device_ptr residual_var = *sample_var_var;
135                 /* Estimate the residual variance between the two filtered halves. */
136                 functions.combine_halves(filtered_a, filtered_b, null_ptr, residual_var, 2, rect);
137
138                 device_ptr final_a = *unfiltered_a,
139                            final_b = *unfiltered_b;
140                 /* Use the residual variance for a second filter pass. */
141                 nlm_state.set_parameters(4, 2, 1.0f, 0.5f);
142                 functions.non_local_means(filtered_a, filtered_b, residual_var, final_a);
143                 functions.non_local_means(filtered_b, filtered_a, residual_var, final_b);
144
145                 /* Combine the two double-filtered halves to a final shadow feature. */
146                 device_sub_ptr shadow_pass(buffer.mem, 4*buffer.pass_stride, buffer.pass_stride);
147                 functions.combine_halves(final_a, final_b, *shadow_pass, null_ptr, 0, rect);
148         }
149
150         /* Prefilter general features. */
151         {
152                 device_sub_ptr unfiltered     (buffer.mem,  8*buffer.pass_stride, buffer.pass_stride);
153                 device_sub_ptr variance       (buffer.mem,  9*buffer.pass_stride, buffer.pass_stride);
154                 device_sub_ptr nlm_temporary_1(buffer.mem, 10*buffer.pass_stride, buffer.pass_stride);
155                 device_sub_ptr nlm_temporary_2(buffer.mem, 11*buffer.pass_stride, buffer.pass_stride);
156                 device_sub_ptr nlm_temporary_3(buffer.mem, 12*buffer.pass_stride, buffer.pass_stride);
157
158                 nlm_state.temporary_1_ptr = *nlm_temporary_1;
159                 nlm_state.temporary_2_ptr = *nlm_temporary_2;
160                 nlm_state.temporary_3_ptr = *nlm_temporary_3;
161
162                 int mean_from[]     = { 0, 1, 2, 12, 6,  7, 8 };
163                 int variance_from[] = { 3, 4, 5, 13, 9, 10, 11};
164                 int pass_to[]       = { 1, 2, 3, 0,  5,  6,  7};
165                 for(int pass = 0; pass < 7; pass++) {
166                         device_sub_ptr feature_pass(buffer.mem, pass_to[pass]*buffer.pass_stride, buffer.pass_stride);
167                         /* Get the unfiltered pass and its variance from the RenderBuffers. */
168                         functions.get_feature(mean_from[pass], variance_from[pass], *unfiltered, *variance);
169                         /* Smooth the pass and store the result in the denoising buffers. */
170                         nlm_state.set_parameters(2, 2, 1.0f, 0.25f);
171                         functions.non_local_means(*unfiltered, *unfiltered, *variance, *feature_pass);
172                 }
173         }
174
175         /* Copy color passes. */
176         {
177                 int mean_from[]     = {20, 21, 22};
178                 int variance_from[] = {23, 24, 25};
179                 int mean_to[]       = { 8,  9, 10};
180                 int variance_to[]   = {11, 12, 13};
181                 int num_color_passes = 3;
182
183                 storage.temporary_color.alloc_to_device(3*buffer.pass_stride, false);
184
185                 for(int pass = 0; pass < num_color_passes; pass++) {
186                         device_sub_ptr color_pass(storage.temporary_color, pass*buffer.pass_stride, buffer.pass_stride);
187                         device_sub_ptr color_var_pass(buffer.mem, variance_to[pass]*buffer.pass_stride, buffer.pass_stride);
188                         functions.get_feature(mean_from[pass], variance_from[pass], *color_pass, *color_var_pass);
189                 }
190
191                 {
192                         device_sub_ptr depth_pass    (buffer.mem,                                 0,   buffer.pass_stride);
193                         device_sub_ptr color_var_pass(buffer.mem, variance_to[0]*buffer.pass_stride, 3*buffer.pass_stride);
194                         device_sub_ptr output_pass   (buffer.mem,     mean_to[0]*buffer.pass_stride, 3*buffer.pass_stride);
195                         functions.detect_outliers(storage.temporary_color.device_pointer, *color_var_pass, *depth_pass, *output_pass);
196                 }
197         }
198
199         storage.w = filter_area.z;
200         storage.h = filter_area.w;
201         storage.transform.alloc_to_device(storage.w*storage.h*TRANSFORM_SIZE, false);
202         storage.rank.alloc_to_device(storage.w*storage.h, false);
203
204         functions.construct_transform();
205
206         storage.temporary_1.alloc_to_device(buffer.w*buffer.h, false);
207         storage.temporary_2.alloc_to_device(buffer.w*buffer.h, false);
208         reconstruction_state.temporary_1_ptr = storage.temporary_1.device_pointer;
209         reconstruction_state.temporary_2_ptr = storage.temporary_2.device_pointer;
210
211         storage.XtWX.alloc_to_device(storage.w*storage.h*XTWX_SIZE, false);
212         storage.XtWY.alloc_to_device(storage.w*storage.h*XTWY_SIZE, false);
213
214         reconstruction_state.filter_rect = make_int4(filter_area.x-rect.x, filter_area.y-rect.y, storage.w, storage.h);
215         int tile_coordinate_offset = filter_area.y*render_buffer.stride + filter_area.x;
216         reconstruction_state.buffer_params = make_int4(render_buffer.offset + tile_coordinate_offset,
217                                                        render_buffer.stride,
218                                                        render_buffer.pass_stride,
219                                                        render_buffer.denoising_clean_offset);
220         reconstruction_state.source_w = rect.z-rect.x;
221         reconstruction_state.source_h = rect.w-rect.y;
222
223         {
224                 device_sub_ptr color_ptr    (buffer.mem,  8*buffer.pass_stride, 3*buffer.pass_stride);
225                 device_sub_ptr color_var_ptr(buffer.mem, 11*buffer.pass_stride, 3*buffer.pass_stride);
226                 functions.reconstruct(*color_ptr, *color_var_ptr, render_buffer.ptr);
227         }
228
229         return true;
230 }
231
232 CCL_NAMESPACE_END