Cycles: Try to avoid infinite loops by catching invalid ray states
This commit is contained in:
@@ -228,6 +228,14 @@ public:
|
||||
DeviceInfo info;
|
||||
virtual const string& error_message() { return error_msg; }
|
||||
bool have_error() { return !error_message().empty(); }
|
||||
virtual void set_error(const string& error)
|
||||
{
|
||||
if(!have_error()) {
|
||||
error_msg = error;
|
||||
}
|
||||
fprintf(stderr, "%s\n", error.c_str());
|
||||
fflush(stderr);
|
||||
}
|
||||
virtual bool show_samples() const { return false; }
|
||||
|
||||
/* statistics */
|
||||
|
@@ -205,6 +205,7 @@ bool DeviceSplitKernel::path_trace(DeviceTask *task,
|
||||
*/
|
||||
device->mem_zero(work_pool_wgs);
|
||||
device->mem_zero(split_data);
|
||||
device->mem_zero(ray_state);
|
||||
|
||||
if(!enqueue_split_kernel_data_init(KernelDimensions(global_size, local_size),
|
||||
subtile,
|
||||
@@ -254,7 +255,15 @@ bool DeviceSplitKernel::path_trace(DeviceTask *task,
|
||||
activeRaysAvailable = false;
|
||||
|
||||
for(int rayStateIter = 0; rayStateIter < global_size[0] * global_size[1]; ++rayStateIter) {
|
||||
if(int8_t(ray_state.get_data()[rayStateIter]) != RAY_INACTIVE) {
|
||||
int8_t state = ray_state.get_data()[rayStateIter];
|
||||
|
||||
if(state != RAY_INACTIVE) {
|
||||
if(state == RAY_INVALID) {
|
||||
/* Something went wrong, abort to avoid looping endlessly. */
|
||||
device->set_error("Split kernel error: invalid ray state");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Not all rays are RAY_INACTIVE. */
|
||||
activeRaysAvailable = true;
|
||||
break;
|
||||
|
@@ -1297,20 +1297,19 @@ enum QueueNumber {
|
||||
#define RAY_STATE_MASK 0x007
|
||||
#define RAY_FLAG_MASK 0x0F8
|
||||
enum RayState {
|
||||
RAY_INVALID = 0,
|
||||
/* Denotes ray is actively involved in path-iteration. */
|
||||
RAY_ACTIVE = 0,
|
||||
RAY_ACTIVE,
|
||||
/* Denotes ray has completed processing all samples and is inactive. */
|
||||
RAY_INACTIVE = 1,
|
||||
RAY_INACTIVE,
|
||||
/* Denoted ray has exited path-iteration and needs to update output buffer. */
|
||||
RAY_UPDATE_BUFFER = 2,
|
||||
RAY_UPDATE_BUFFER,
|
||||
/* Donotes ray has hit background */
|
||||
RAY_HIT_BACKGROUND = 3,
|
||||
RAY_HIT_BACKGROUND,
|
||||
/* Denotes ray has to be regenerated */
|
||||
RAY_TO_REGENERATE = 4,
|
||||
RAY_TO_REGENERATE,
|
||||
/* Denotes ray has been regenerated */
|
||||
RAY_REGENERATED = 5,
|
||||
/* Denotes ray should skip direct lighting */
|
||||
RAY_SKIP_DL = 6,
|
||||
RAY_REGENERATED,
|
||||
/* Flag's ray has to execute shadow blocked function in AO part */
|
||||
RAY_SHADOW_RAY_CAST_AO = 16,
|
||||
/* Flag's ray has to execute shadow blocked function in direct lighting part. */
|
||||
|
Reference in New Issue
Block a user