diff options
author | Brecht Van Lommel <brecht@blender.org> | 2021-09-16 22:17:52 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2021-09-16 22:20:58 +0300 |
commit | ca9ece306400b546f97f956dc6f80f4371ce3d2b (patch) | |
tree | a3d71690b85289c1bde3cb66d35f4856f44348c2 | |
parent | 3b38531b4528f3c4e0cde7f82f0aebfaaedc5479 (diff) |
Fix T91426: don't display outdated denoised result when increasing samples
-rw-r--r-- | intern/cycles/integrator/path_trace.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/integrator/render_scheduler.cpp | 24 | ||||
-rw-r--r-- | intern/cycles/integrator/render_scheduler.h | 19 |
3 files changed, 33 insertions, 18 deletions
diff --git a/intern/cycles/integrator/path_trace.cpp b/intern/cycles/integrator/path_trace.cpp index 856e90697dc..6973a86daac 100644 --- a/intern/cycles/integrator/path_trace.cpp +++ b/intern/cycles/integrator/path_trace.cpp @@ -522,7 +522,7 @@ void PathTrace::draw() void PathTrace::update_display(const RenderWork &render_work) { - if (!render_work.update_display) { + if (!render_work.display.update) { return; } @@ -561,8 +561,10 @@ void PathTrace::update_display(const RenderWork &render_work) return; } - const PassMode pass_mode = render_state_.has_denoised_result ? PassMode::DENOISED : - PassMode::NOISY; + const PassMode pass_mode = render_work.display.use_denoised_result && + render_state_.has_denoised_result ? + PassMode::DENOISED : + PassMode::NOISY; /* TODO(sergey): When using multi-device rendering map the GPUDisplay once and copy data from all * works in parallel. */ diff --git a/intern/cycles/integrator/render_scheduler.cpp b/intern/cycles/integrator/render_scheduler.cpp index 45a5f4b8bd5..7a842f2e4cd 100644 --- a/intern/cycles/integrator/render_scheduler.cpp +++ b/intern/cycles/integrator/render_scheduler.cpp @@ -185,10 +185,11 @@ bool RenderScheduler::render_work_reschedule_on_converge(RenderWork &render_work state_.path_trace_finished = true; - bool denoiser_delayed; - render_work.tile.denoise = work_need_denoise(denoiser_delayed); + bool denoiser_delayed, denoiser_ready_to_display; + render_work.tile.denoise = work_need_denoise(denoiser_delayed, denoiser_ready_to_display); - render_work.update_display = work_need_update_display(denoiser_delayed); + render_work.display.update = work_need_update_display(denoiser_delayed); + render_work.display.use_denoised_result = denoiser_ready_to_display; return false; } @@ -261,7 +262,7 @@ void RenderScheduler::render_work_reschedule_on_cancel(RenderWork &render_work) * buffers. And the buffers might have been freed from the device, so display update is not * possible. */ if (has_rendered_samples && !state_.full_frame_was_written) { - render_work.update_display = true; + render_work.display.update = true; } } @@ -327,12 +328,13 @@ RenderWork RenderScheduler::get_render_work() render_work.adaptive_sampling.threshold = work_adaptive_threshold(); render_work.adaptive_sampling.reset = false; - bool denoiser_delayed; - render_work.tile.denoise = work_need_denoise(denoiser_delayed); + bool denoiser_delayed, denoiser_ready_to_display; + render_work.tile.denoise = work_need_denoise(denoiser_delayed, denoiser_ready_to_display); render_work.tile.write = done(); - render_work.update_display = work_need_update_display(denoiser_delayed); + render_work.display.update = work_need_update_display(denoiser_delayed); + render_work.display.use_denoised_result = denoiser_ready_to_display; if (done()) { set_postprocess_render_work(&render_work); @@ -354,7 +356,7 @@ void RenderScheduler::update_state_for_render_work(const RenderWork &render_work /* A fallback display update time, for the case there is an error of display update, or when * there is no display at all. */ - if (render_work.update_display) { + if (render_work.display.update) { state_.last_display_update_time = time_now; state_.last_display_update_sample = state_.num_rendered_samples; } @@ -389,7 +391,7 @@ bool RenderScheduler::set_postprocess_render_work(RenderWork *render_work) } if (any_scheduled) { - render_work->update_display = true; + render_work->display.update = true; } return any_scheduled; @@ -870,9 +872,10 @@ float RenderScheduler::work_adaptive_threshold() const return max(state_.adaptive_sampling_threshold, adaptive_sampling_.threshold); } -bool RenderScheduler::work_need_denoise(bool &delayed) +bool RenderScheduler::work_need_denoise(bool &delayed, bool &ready_to_display) { delayed = false; + ready_to_display = true; if (!denoiser_params_.use) { /* Denoising is disabled, no need to scheduler work for it. */ @@ -907,6 +910,7 @@ bool RenderScheduler::work_need_denoise(bool &delayed) /* Do not denoise until the sample at which denoising should start is reached. */ if (num_samples_finished < denoiser_params_.start_sample) { + ready_to_display = false; return false; } diff --git a/intern/cycles/integrator/render_scheduler.h b/intern/cycles/integrator/render_scheduler.h index 9c9e758c8c3..9c3b6888f83 100644 --- a/intern/cycles/integrator/render_scheduler.h +++ b/intern/cycles/integrator/render_scheduler.h @@ -75,8 +75,14 @@ class RenderWork { bool denoise = false; } full; - /* Display which is used to visualize render result is to be updated for the new render. */ - bool update_display = false; + /* Display which is used to visualize render result. */ + struct { + /* Display needs to be updated for the new render. */ + bool update = false; + + /* Display can use denoised result if available. */ + bool use_denoised_result = true; + } display; /* Re-balance multi-device scheduling after rendering this work. * Note that the scheduler does not know anything abouce devices, so if there is only a single @@ -87,7 +93,7 @@ class RenderWork { * work. */ inline operator bool() const { - return path_trace.num_samples || adaptive_sampling.filter || update_display || tile.denoise || + return path_trace.num_samples || adaptive_sampling.filter || display.update || tile.denoise || tile.write || full.write || full.denoise; } }; @@ -253,8 +259,11 @@ class RenderScheduler { * often. * * The delayed will be true when the denoiser is configured for use, but it was delayed for a - * later sample, to reduce overhead. */ - bool work_need_denoise(bool &delayed); + * later sample, to reduce overhead. + * + * ready_to_display will be false if we may have a denoised result that is outdated due to + * increased samples. */ + bool work_need_denoise(bool &delayed, bool &ready_to_display); /* Check whether current work need to update display. * |