device_denoising.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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. #include "device/device_denoising.h"
  17. #include "kernel/filter/filter_defines.h"
  18. CCL_NAMESPACE_BEGIN
  19. DenoisingTask::DenoisingTask(Device *device, const DeviceTask &task)
  20. : tile_info_mem(device, "denoising tile info mem", MEM_READ_WRITE),
  21. profiler(NULL),
  22. storage(device),
  23. buffer(device),
  24. device(device)
  25. {
  26. radius = task.denoising.radius;
  27. nlm_k_2 = powf(2.0f, lerp(-5.0f, 3.0f, task.denoising.strength));
  28. if (task.denoising.relative_pca) {
  29. pca_threshold = -powf(10.0f, lerp(-8.0f, 0.0f, task.denoising.feature_strength));
  30. }
  31. else {
  32. pca_threshold = powf(10.0f, lerp(-5.0f, 3.0f, task.denoising.feature_strength));
  33. }
  34. render_buffer.frame_stride = task.frame_stride;
  35. render_buffer.pass_stride = task.pass_stride;
  36. render_buffer.offset = task.pass_denoising_data;
  37. target_buffer.pass_stride = task.target_pass_stride;
  38. target_buffer.denoising_clean_offset = task.pass_denoising_clean;
  39. target_buffer.offset = 0;
  40. functions.map_neighbor_tiles = function_bind(task.map_neighbor_tiles, _1, device);
  41. functions.unmap_neighbor_tiles = function_bind(task.unmap_neighbor_tiles, _1, device);
  42. tile_info = (TileInfo *)tile_info_mem.alloc(sizeof(TileInfo) / sizeof(int));
  43. tile_info->from_render = task.denoising_from_render ? 1 : 0;
  44. tile_info->frames[0] = 0;
  45. tile_info->num_frames = min(task.denoising_frames.size() + 1, DENOISE_MAX_FRAMES);
  46. for (int i = 1; i < tile_info->num_frames; i++) {
  47. tile_info->frames[i] = task.denoising_frames[i - 1];
  48. }
  49. write_passes = task.denoising_write_passes;
  50. do_filter = task.denoising_do_filter;
  51. }
  52. DenoisingTask::~DenoisingTask()
  53. {
  54. storage.XtWX.free();
  55. storage.XtWY.free();
  56. storage.transform.free();
  57. storage.rank.free();
  58. buffer.mem.free();
  59. buffer.temporary_mem.free();
  60. tile_info_mem.free();
  61. }
  62. void DenoisingTask::set_render_buffer(RenderTile *rtiles)
  63. {
  64. for (int i = 0; i < 9; i++) {
  65. tile_info->offsets[i] = rtiles[i].offset;
  66. tile_info->strides[i] = rtiles[i].stride;
  67. tile_info->buffers[i] = rtiles[i].buffer;
  68. }
  69. tile_info->x[0] = rtiles[3].x;
  70. tile_info->x[1] = rtiles[4].x;
  71. tile_info->x[2] = rtiles[5].x;
  72. tile_info->x[3] = rtiles[5].x + rtiles[5].w;
  73. tile_info->y[0] = rtiles[1].y;
  74. tile_info->y[1] = rtiles[4].y;
  75. tile_info->y[2] = rtiles[7].y;
  76. tile_info->y[3] = rtiles[7].y + rtiles[7].h;
  77. target_buffer.offset = rtiles[9].offset;
  78. target_buffer.stride = rtiles[9].stride;
  79. target_buffer.ptr = rtiles[9].buffer;
  80. if (write_passes && rtiles[9].buffers) {
  81. target_buffer.denoising_output_offset =
  82. rtiles[9].buffers->params.get_denoising_prefiltered_offset();
  83. }
  84. else {
  85. target_buffer.denoising_output_offset = 0;
  86. }
  87. tile_info_mem.copy_to_device();
  88. }
  89. void DenoisingTask::setup_denoising_buffer()
  90. {
  91. /* Expand filter_area by radius pixels and clamp the result to the extent of the neighboring
  92. * tiles */
  93. rect = rect_from_shape(filter_area.x, filter_area.y, filter_area.z, filter_area.w);
  94. rect = rect_expand(rect, radius);
  95. rect = rect_clip(rect,
  96. make_int4(tile_info->x[0], tile_info->y[0], tile_info->x[3], tile_info->y[3]));
  97. buffer.use_intensity = write_passes || (tile_info->num_frames > 1);
  98. buffer.passes = buffer.use_intensity ? 15 : 14;
  99. buffer.width = rect.z - rect.x;
  100. buffer.stride = align_up(buffer.width, 4);
  101. buffer.h = rect.w - rect.y;
  102. int alignment_floats = divide_up(device->mem_sub_ptr_alignment(), sizeof(float));
  103. buffer.pass_stride = align_up(buffer.stride * buffer.h, alignment_floats);
  104. buffer.frame_stride = buffer.pass_stride * buffer.passes;
  105. /* Pad the total size by four floats since the SIMD kernels might go a bit over the end. */
  106. int mem_size = align_up(tile_info->num_frames * buffer.frame_stride + 4, alignment_floats);
  107. buffer.mem.alloc_to_device(mem_size, false);
  108. buffer.use_time = (tile_info->num_frames > 1);
  109. /* CPUs process shifts sequentially while GPUs process them in parallel. */
  110. int num_layers;
  111. if (buffer.gpu_temporary_mem) {
  112. /* Shadowing prefiltering uses a radius of 6, so allocate at least that much. */
  113. int max_radius = max(radius, 6);
  114. int num_shifts = (2 * max_radius + 1) * (2 * max_radius + 1);
  115. num_layers = 2 * num_shifts + 1;
  116. }
  117. else {
  118. num_layers = 3;
  119. }
  120. /* Allocate two layers per shift as well as one for the weight accumulation. */
  121. buffer.temporary_mem.alloc_to_device(num_layers * buffer.pass_stride);
  122. }
  123. void DenoisingTask::prefilter_shadowing()
  124. {
  125. device_ptr null_ptr = (device_ptr)0;
  126. device_sub_ptr unfiltered_a(buffer.mem, 0, buffer.pass_stride);
  127. device_sub_ptr unfiltered_b(buffer.mem, 1 * buffer.pass_stride, buffer.pass_stride);
  128. device_sub_ptr sample_var(buffer.mem, 2 * buffer.pass_stride, buffer.pass_stride);
  129. device_sub_ptr sample_var_var(buffer.mem, 3 * buffer.pass_stride, buffer.pass_stride);
  130. device_sub_ptr buffer_var(buffer.mem, 5 * buffer.pass_stride, buffer.pass_stride);
  131. device_sub_ptr filtered_var(buffer.mem, 6 * buffer.pass_stride, buffer.pass_stride);
  132. /* Get the A/B unfiltered passes, the combined sample variance, the estimated variance of the
  133. * sample variance and the buffer variance. */
  134. functions.divide_shadow(*unfiltered_a, *unfiltered_b, *sample_var, *sample_var_var, *buffer_var);
  135. /* Smooth the (generally pretty noisy) buffer variance using the spatial information from the
  136. * sample variance. */
  137. nlm_state.set_parameters(6, 3, 4.0f, 1.0f, false);
  138. functions.non_local_means(*buffer_var, *sample_var, *sample_var_var, *filtered_var);
  139. /* Reuse memory, the previous data isn't needed anymore. */
  140. device_ptr filtered_a = *buffer_var, filtered_b = *sample_var;
  141. /* Use the smoothed variance to filter the two shadow half images using each other for weight
  142. * calculation. */
  143. nlm_state.set_parameters(5, 3, 1.0f, 0.25f, false);
  144. functions.non_local_means(*unfiltered_a, *unfiltered_b, *filtered_var, filtered_a);
  145. functions.non_local_means(*unfiltered_b, *unfiltered_a, *filtered_var, filtered_b);
  146. device_ptr residual_var = *sample_var_var;
  147. /* Estimate the residual variance between the two filtered halves. */
  148. functions.combine_halves(filtered_a, filtered_b, null_ptr, residual_var, 2, rect);
  149. device_ptr final_a = *unfiltered_a, final_b = *unfiltered_b;
  150. /* Use the residual variance for a second filter pass. */
  151. nlm_state.set_parameters(4, 2, 1.0f, 0.5f, false);
  152. functions.non_local_means(filtered_a, filtered_b, residual_var, final_a);
  153. functions.non_local_means(filtered_b, filtered_a, residual_var, final_b);
  154. /* Combine the two double-filtered halves to a final shadow feature. */
  155. device_sub_ptr shadow_pass(buffer.mem, 4 * buffer.pass_stride, buffer.pass_stride);
  156. functions.combine_halves(final_a, final_b, *shadow_pass, null_ptr, 0, rect);
  157. }
  158. void DenoisingTask::prefilter_features()
  159. {
  160. device_sub_ptr unfiltered(buffer.mem, 8 * buffer.pass_stride, buffer.pass_stride);
  161. device_sub_ptr variance(buffer.mem, 9 * buffer.pass_stride, buffer.pass_stride);
  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(
  167. buffer.mem, pass_to[pass] * buffer.pass_stride, buffer.pass_stride);
  168. /* Get the unfiltered pass and its variance from the RenderBuffers. */
  169. functions.get_feature(mean_from[pass],
  170. variance_from[pass],
  171. *unfiltered,
  172. *variance,
  173. 1.0f / render_buffer.samples);
  174. /* Smooth the pass and store the result in the denoising buffers. */
  175. nlm_state.set_parameters(2, 2, 1.0f, 0.25f, false);
  176. functions.non_local_means(*unfiltered, *unfiltered, *variance, *feature_pass);
  177. }
  178. }
  179. void DenoisingTask::prefilter_color()
  180. {
  181. int mean_from[] = {20, 21, 22};
  182. int variance_from[] = {23, 24, 25};
  183. int mean_to[] = {8, 9, 10};
  184. int variance_to[] = {11, 12, 13};
  185. int num_color_passes = 3;
  186. device_only_memory<float> temporary_color(device, "denoising temporary color");
  187. temporary_color.alloc_to_device(6 * buffer.pass_stride, false);
  188. for (int pass = 0; pass < num_color_passes; pass++) {
  189. device_sub_ptr color_pass(temporary_color, pass * buffer.pass_stride, buffer.pass_stride);
  190. device_sub_ptr color_var_pass(
  191. temporary_color, (pass + 3) * buffer.pass_stride, buffer.pass_stride);
  192. functions.get_feature(mean_from[pass],
  193. variance_from[pass],
  194. *color_pass,
  195. *color_var_pass,
  196. 1.0f / render_buffer.samples);
  197. }
  198. device_sub_ptr depth_pass(buffer.mem, 0, buffer.pass_stride);
  199. device_sub_ptr color_var_pass(
  200. buffer.mem, variance_to[0] * buffer.pass_stride, 3 * buffer.pass_stride);
  201. device_sub_ptr output_pass(buffer.mem, mean_to[0] * buffer.pass_stride, 3 * buffer.pass_stride);
  202. functions.detect_outliers(
  203. temporary_color.device_pointer, *color_var_pass, *depth_pass, *output_pass);
  204. if (buffer.use_intensity) {
  205. device_sub_ptr intensity_pass(buffer.mem, 14 * buffer.pass_stride, buffer.pass_stride);
  206. nlm_state.set_parameters(radius, 4, 2.0f, nlm_k_2 * 4.0f, true);
  207. functions.non_local_means(*output_pass, *output_pass, *color_var_pass, *intensity_pass);
  208. }
  209. }
  210. void DenoisingTask::load_buffer()
  211. {
  212. device_ptr null_ptr = (device_ptr)0;
  213. int original_offset = render_buffer.offset;
  214. int num_passes = buffer.use_intensity ? 15 : 14;
  215. for (int i = 0; i < tile_info->num_frames; i++) {
  216. for (int pass = 0; pass < num_passes; pass++) {
  217. device_sub_ptr to_pass(
  218. buffer.mem, i * buffer.frame_stride + pass * buffer.pass_stride, buffer.pass_stride);
  219. bool is_variance = (pass >= 11) && (pass <= 13);
  220. functions.get_feature(
  221. pass, -1, *to_pass, null_ptr, is_variance ? (1.0f / render_buffer.samples) : 1.0f);
  222. }
  223. render_buffer.offset += render_buffer.frame_stride;
  224. }
  225. render_buffer.offset = original_offset;
  226. }
  227. void DenoisingTask::write_buffer()
  228. {
  229. reconstruction_state.buffer_params = make_int4(target_buffer.offset,
  230. target_buffer.stride,
  231. target_buffer.pass_stride,
  232. target_buffer.denoising_clean_offset);
  233. int num_passes = buffer.use_intensity ? 15 : 14;
  234. for (int pass = 0; pass < num_passes; pass++) {
  235. device_sub_ptr from_pass(buffer.mem, pass * buffer.pass_stride, buffer.pass_stride);
  236. int out_offset = pass + target_buffer.denoising_output_offset;
  237. functions.write_feature(out_offset, *from_pass, target_buffer.ptr);
  238. }
  239. }
  240. void DenoisingTask::construct_transform()
  241. {
  242. storage.w = filter_area.z;
  243. storage.h = filter_area.w;
  244. storage.transform.alloc_to_device(storage.w * storage.h * TRANSFORM_SIZE, false);
  245. storage.rank.alloc_to_device(storage.w * storage.h, false);
  246. functions.construct_transform();
  247. }
  248. void DenoisingTask::reconstruct()
  249. {
  250. storage.XtWX.alloc_to_device(storage.w * storage.h * XTWX_SIZE, false);
  251. storage.XtWY.alloc_to_device(storage.w * storage.h * XTWY_SIZE, false);
  252. storage.XtWX.zero_to_device();
  253. storage.XtWY.zero_to_device();
  254. reconstruction_state.filter_window = rect_from_shape(
  255. filter_area.x - rect.x, filter_area.y - rect.y, storage.w, storage.h);
  256. int tile_coordinate_offset = filter_area.y * target_buffer.stride + filter_area.x;
  257. reconstruction_state.buffer_params = make_int4(target_buffer.offset + tile_coordinate_offset,
  258. target_buffer.stride,
  259. target_buffer.pass_stride,
  260. target_buffer.denoising_clean_offset);
  261. reconstruction_state.source_w = rect.z - rect.x;
  262. reconstruction_state.source_h = rect.w - rect.y;
  263. device_sub_ptr color_ptr(buffer.mem, 8 * buffer.pass_stride, 3 * buffer.pass_stride);
  264. device_sub_ptr color_var_ptr(buffer.mem, 11 * buffer.pass_stride, 3 * buffer.pass_stride);
  265. for (int f = 0; f < tile_info->num_frames; f++) {
  266. device_ptr scale_ptr = 0;
  267. device_sub_ptr *scale_sub_ptr = NULL;
  268. if (tile_info->frames[f] != 0 && (tile_info->num_frames > 1)) {
  269. scale_sub_ptr = new device_sub_ptr(buffer.mem, 14 * buffer.pass_stride, buffer.pass_stride);
  270. scale_ptr = **scale_sub_ptr;
  271. }
  272. functions.accumulate(*color_ptr, *color_var_ptr, scale_ptr, f);
  273. delete scale_sub_ptr;
  274. }
  275. functions.solve(target_buffer.ptr);
  276. }
  277. void DenoisingTask::run_denoising(RenderTile *tile)
  278. {
  279. RenderTile rtiles[10];
  280. rtiles[4] = *tile;
  281. functions.map_neighbor_tiles(rtiles);
  282. set_render_buffer(rtiles);
  283. setup_denoising_buffer();
  284. if (tile_info->from_render) {
  285. prefilter_shadowing();
  286. prefilter_features();
  287. prefilter_color();
  288. }
  289. else {
  290. load_buffer();
  291. }
  292. if (do_filter) {
  293. construct_transform();
  294. reconstruct();
  295. }
  296. if (write_passes) {
  297. write_buffer();
  298. }
  299. functions.unmap_neighbor_tiles(rtiles);
  300. }
  301. CCL_NAMESPACE_END