Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2021-09-16 22:17:52 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-09-16 22:20:58 +0300
commitca9ece306400b546f97f956dc6f80f4371ce3d2b (patch)
treea3d71690b85289c1bde3cb66d35f4856f44348c2
parent3b38531b4528f3c4e0cde7f82f0aebfaaedc5479 (diff)
Fix T91426: don't display outdated denoised result when increasing samples
-rw-r--r--intern/cycles/integrator/path_trace.cpp8
-rw-r--r--intern/cycles/integrator/render_scheduler.cpp24
-rw-r--r--intern/cycles/integrator/render_scheduler.h19
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.
*