diff options
author | Sergey Sharybin <sergey@blender.org> | 2021-09-21 18:03:22 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey@blender.org> | 2021-10-05 17:19:14 +0300 |
commit | 6e268a749fee16b442bcb3fba6cb6e08850d8389 (patch) | |
tree | effa2244461bc000856218ec44b8990305aac91c /intern/cycles/integrator | |
parent | 758f3f7456ac1e31f411c4ac1b19760ad6e5539c (diff) |
Fix adaptive sampling artifacts on tile boundaries
Implement an overscan support for tiles, so that adaptive sampling can
rely on the pixels neighbourhood.
Differential Revision: https://developer.blender.org/D12599
Diffstat (limited to 'intern/cycles/integrator')
-rw-r--r-- | intern/cycles/integrator/denoiser_oidn.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/integrator/pass_accessor_cpu.cpp | 45 | ||||
-rw-r--r-- | intern/cycles/integrator/pass_accessor_gpu.cpp | 15 | ||||
-rw-r--r-- | intern/cycles/integrator/path_trace.cpp | 14 | ||||
-rw-r--r-- | intern/cycles/integrator/path_trace_work.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/integrator/path_trace_work_gpu.cpp | 12 |
6 files changed, 62 insertions, 38 deletions
diff --git a/intern/cycles/integrator/denoiser_oidn.cpp b/intern/cycles/integrator/denoiser_oidn.cpp index 7fc2b2b1892..ee3b62668a7 100644 --- a/intern/cycles/integrator/denoiser_oidn.cpp +++ b/intern/cycles/integrator/denoiser_oidn.cpp @@ -289,7 +289,13 @@ class OIDNDenoiseContext { * pixels. */ const PassAccessorCPU pass_accessor(pass_access_info, 1.0f, num_samples_); - pass_accessor.get_render_tile_pixels(render_buffers_, buffer_params_, destination); + BufferParams buffer_params = buffer_params_; + buffer_params.window_x = 0; + buffer_params.window_y = 0; + buffer_params.window_width = buffer_params.width; + buffer_params.window_height = buffer_params.height; + + pass_accessor.get_render_tile_pixels(render_buffers_, buffer_params, destination); } /* Read pass pixels using PassAccessor into a temporary buffer which is owned by the pass.. */ diff --git a/intern/cycles/integrator/pass_accessor_cpu.cpp b/intern/cycles/integrator/pass_accessor_cpu.cpp index 3c6691f6d43..80908271ff6 100644 --- a/intern/cycles/integrator/pass_accessor_cpu.cpp +++ b/intern/cycles/integrator/pass_accessor_cpu.cpp @@ -99,17 +99,22 @@ inline void PassAccessorCPU::run_get_pass_kernel_processor_float( { DCHECK_EQ(destination.stride, 0) << "Custom stride for float destination is not implemented."; - const float *buffer_data = render_buffers->buffer.data(); + const int64_t pass_stride = buffer_params.pass_stride; + const int64_t buffer_row_stride = buffer_params.stride * buffer_params.pass_stride; + + const float *window_data = render_buffers->buffer.data() + buffer_params.window_x * pass_stride + + buffer_params.window_y * buffer_row_stride; + const int pixel_stride = destination.pixel_stride ? destination.pixel_stride : destination.num_components; - tbb::parallel_for(0, buffer_params.height, [&](int64_t y) { - int64_t pixel_index = y * buffer_params.width; - for (int64_t x = 0; x < buffer_params.width; ++x, ++pixel_index) { - const int64_t input_pixel_offset = pixel_index * buffer_params.pass_stride; - const float *buffer = buffer_data + input_pixel_offset; - float *pixel = destination.pixels + (pixel_index + destination.offset) * pixel_stride; + tbb::parallel_for(0, buffer_params.window_height, [&](int64_t y) { + const float *buffer = window_data + y * buffer_row_stride; + float *pixel = destination.pixels + + (y * buffer_params.width + destination.offset) * pixel_stride; + for (int64_t x = 0; x < buffer_params.window_width; + ++x, buffer += pass_stride, pixel += pixel_stride) { processor(kfilm_convert, buffer, pixel); } }); @@ -123,26 +128,28 @@ inline void PassAccessorCPU::run_get_pass_kernel_processor_half_rgba( const Destination &destination, const Processor &processor) const { - const float *buffer_data = render_buffers->buffer.data(); + const int64_t pass_stride = buffer_params.pass_stride; + const int64_t buffer_row_stride = buffer_params.stride * buffer_params.pass_stride; + + const float *window_data = render_buffers->buffer.data() + buffer_params.window_x * pass_stride + + buffer_params.window_y * buffer_row_stride; half4 *dst_start = destination.pixels_half_rgba + destination.offset; const int destination_stride = destination.stride != 0 ? destination.stride : buffer_params.width; - tbb::parallel_for(0, buffer_params.height, [&](int64_t y) { - int64_t pixel_index = y * buffer_params.width; - half4 *dst_row_start = dst_start + y * destination_stride; - for (int64_t x = 0; x < buffer_params.width; ++x, ++pixel_index) { - const int64_t input_pixel_offset = pixel_index * buffer_params.pass_stride; - const float *buffer = buffer_data + input_pixel_offset; + tbb::parallel_for(0, buffer_params.window_height, [&](int64_t y) { + const float *buffer = window_data + y * buffer_row_stride; + half4 *pixel = dst_start + y * destination_stride; + for (int64_t x = 0; x < buffer_params.window_width; ++x, buffer += pass_stride, ++pixel) { - float pixel[4]; - processor(kfilm_convert, buffer, pixel); + float pixel_rgba[4]; + processor(kfilm_convert, buffer, pixel_rgba); - film_apply_pass_pixel_overlays_rgba(kfilm_convert, buffer, pixel); + film_apply_pass_pixel_overlays_rgba(kfilm_convert, buffer, pixel_rgba); - half4 *pixel_half_rgba = dst_row_start + x; - float4_store_half(&pixel_half_rgba->x, make_float4(pixel[0], pixel[1], pixel[2], pixel[3])); + float4_store_half(&pixel->x, + make_float4(pixel_rgba[0], pixel_rgba[1], pixel_rgba[2], pixel_rgba[3])); } }); } diff --git a/intern/cycles/integrator/pass_accessor_gpu.cpp b/intern/cycles/integrator/pass_accessor_gpu.cpp index eb80ba99655..7b01d061708 100644 --- a/intern/cycles/integrator/pass_accessor_gpu.cpp +++ b/intern/cycles/integrator/pass_accessor_gpu.cpp @@ -43,10 +43,13 @@ void PassAccessorGPU::run_film_convert_kernels(DeviceKernel kernel, KernelFilmConvert kfilm_convert; init_kernel_film_convert(&kfilm_convert, buffer_params, destination); - const int work_size = buffer_params.width * buffer_params.height; + const int work_size = buffer_params.window_width * buffer_params.window_height; const int destination_stride = destination.stride != 0 ? destination.stride : - buffer_params.width; + buffer_params.window_width; + + const int offset = buffer_params.window_x * buffer_params.pass_stride + + buffer_params.window_y * buffer_params.stride * buffer_params.pass_stride; if (destination.d_pixels) { DCHECK_EQ(destination.stride, 0) << "Custom stride for float destination is not implemented."; @@ -55,8 +58,8 @@ void PassAccessorGPU::run_film_convert_kernels(DeviceKernel kernel, const_cast<device_ptr *>(&destination.d_pixels), const_cast<device_ptr *>(&render_buffers->buffer.device_pointer), const_cast<int *>(&work_size), - const_cast<int *>(&buffer_params.width), - const_cast<int *>(&buffer_params.offset), + const_cast<int *>(&buffer_params.window_width), + const_cast<int *>(&offset), const_cast<int *>(&buffer_params.stride), const_cast<int *>(&destination.offset), const_cast<int *>(&destination_stride)}; @@ -70,8 +73,8 @@ void PassAccessorGPU::run_film_convert_kernels(DeviceKernel kernel, const_cast<device_ptr *>(&destination.d_pixels_half_rgba), const_cast<device_ptr *>(&render_buffers->buffer.device_pointer), const_cast<int *>(&work_size), - const_cast<int *>(&buffer_params.width), - const_cast<int *>(&buffer_params.offset), + const_cast<int *>(&buffer_params.window_width), + const_cast<int *>(&offset), const_cast<int *>(&buffer_params.stride), const_cast<int *>(&destination.offset), const_cast<int *>(&destination_stride)}; diff --git a/intern/cycles/integrator/path_trace.cpp b/intern/cycles/integrator/path_trace.cpp index 7624b244175..3ea5c3c64b8 100644 --- a/intern/cycles/integrator/path_trace.cpp +++ b/intern/cycles/integrator/path_trace.cpp @@ -282,6 +282,12 @@ static BufferParams scale_buffer_params(const BufferParams ¶ms, int resoluti scaled_params.width = max(1, params.width / resolution_divider); scaled_params.height = max(1, params.height / resolution_divider); + + scaled_params.window_x = params.window_x / resolution_divider; + scaled_params.window_y = params.window_y / resolution_divider; + scaled_params.window_width = params.window_width / resolution_divider; + scaled_params.window_height = params.window_height / resolution_divider; + scaled_params.full_x = params.full_x / resolution_divider; scaled_params.full_y = params.full_y / resolution_divider; scaled_params.full_width = params.full_width / resolution_divider; @@ -1005,12 +1011,12 @@ bool PathTrace::set_render_tile_pixels(PassAccessor &pass_accessor, int2 PathTrace::get_render_tile_size() const { if (full_frame_state_.render_buffers) { - return make_int2(full_frame_state_.render_buffers->params.width, - full_frame_state_.render_buffers->params.height); + return make_int2(full_frame_state_.render_buffers->params.window_width, + full_frame_state_.render_buffers->params.window_height); } const Tile &tile = tile_manager_.get_current_tile(); - return make_int2(tile.width, tile.height); + return make_int2(tile.window_width, tile.window_height); } int2 PathTrace::get_render_tile_offset() const @@ -1020,7 +1026,7 @@ int2 PathTrace::get_render_tile_offset() const } const Tile &tile = tile_manager_.get_current_tile(); - return make_int2(tile.x, tile.y); + return make_int2(tile.x + tile.window_x, tile.y + tile.window_y); } int2 PathTrace::get_render_size() const diff --git a/intern/cycles/integrator/path_trace_work.cpp b/intern/cycles/integrator/path_trace_work.cpp index c29177907c9..f626beb0aaa 100644 --- a/intern/cycles/integrator/path_trace_work.cpp +++ b/intern/cycles/integrator/path_trace_work.cpp @@ -191,8 +191,10 @@ PassAccessor::Destination PathTraceWork::get_display_destination_template( PassAccessor::Destination destination(film_->get_display_pass()); const int2 display_texture_size = display->get_texture_size(); - const int texture_x = effective_buffer_params_.full_x - effective_full_params_.full_x; - const int texture_y = effective_buffer_params_.full_y - effective_full_params_.full_y; + const int texture_x = effective_buffer_params_.full_x - effective_full_params_.full_x + + effective_buffer_params_.window_x; + const int texture_y = effective_buffer_params_.full_y - effective_full_params_.full_y + + effective_buffer_params_.window_y; destination.offset = texture_y * display_texture_size.x + texture_x; destination.stride = display_texture_size.x; diff --git a/intern/cycles/integrator/path_trace_work_gpu.cpp b/intern/cycles/integrator/path_trace_work_gpu.cpp index 7babc9d09fa..c29b0fb039e 100644 --- a/intern/cycles/integrator/path_trace_work_gpu.cpp +++ b/intern/cycles/integrator/path_trace_work_gpu.cpp @@ -737,13 +737,13 @@ void PathTraceWorkGPU::copy_to_display_naive(PathTraceDisplay *display, { const int full_x = effective_buffer_params_.full_x; const int full_y = effective_buffer_params_.full_y; - const int width = effective_buffer_params_.width; - const int height = effective_buffer_params_.height; - const int final_width = buffers_->params.width; - const int final_height = buffers_->params.height; + const int width = effective_buffer_params_.window_width; + const int height = effective_buffer_params_.window_height; + const int final_width = buffers_->params.window_width; + const int final_height = buffers_->params.window_height; - const int texture_x = full_x - effective_full_params_.full_x; - const int texture_y = full_y - effective_full_params_.full_y; + const int texture_x = full_x - effective_full_params_.full_x + effective_buffer_params_.window_x; + const int texture_y = full_y - effective_full_params_.full_y + effective_buffer_params_.window_y; /* Re-allocate display memory if needed, and make sure the device pointer is allocated. * |