Cycles: Allow samples to finish in split kernel to avoid artifacts when canceling

Previously canceling a render done by the split kernel could cause artifacts
such as very bright or dark tiles. This was caused by unfinished samples
being included in the output buffer. To avoid this we now wait till all the
currently rendering samples have finished, up to a limit of twice the
expected time for them to finish (currently this is no more than 20 seconds,
but usually its much less). If samples still haven't finished by then we
stop anyways in case there's an endless loop occurring.
This commit is contained in:
Mai Lavelle 2017-04-26 10:22:48 -04:00 committed by Julian Eisel
parent c6bf5d4724
commit d8ce3ed140
1 changed files with 10 additions and 2 deletions

View File

@ -227,6 +227,7 @@ bool DeviceSplitKernel::path_trace(DeviceTask *task,
ENQUEUE_SPLIT_KERNEL(path_init, global_size, local_size);
bool activeRaysAvailable = true;
double cancel_time = DBL_MAX;
while(activeRaysAvailable) {
/* Do path-iteration in host [Enqueue Path-iteration kernels. */
@ -247,7 +248,14 @@ bool DeviceSplitKernel::path_trace(DeviceTask *task,
ENQUEUE_SPLIT_KERNEL(queue_enqueue, global_size, local_size);
ENQUEUE_SPLIT_KERNEL(buffer_update, global_size, local_size);
if(task->get_cancel()) {
if(task->get_cancel() && cancel_time == DBL_MAX) {
/* Wait up to twice as many seconds for current samples to finish
* to avoid artifacts in render result from ending too soon.
*/
cancel_time = time_dt() + 2.0 * time_multiplier;
}
if(time_dt() > cancel_time) {
return true;
}
}
@ -271,7 +279,7 @@ bool DeviceSplitKernel::path_trace(DeviceTask *task,
}
}
if(task->get_cancel()) {
if(time_dt() > cancel_time) {
return true;
}
}