diff options
author | Mai Lavelle <mai.lavelle@gmail.com> | 2017-03-11 15:03:17 +0300 |
---|---|---|
committer | Mai Lavelle <mai.lavelle@gmail.com> | 2017-03-14 13:22:57 +0300 |
commit | 8dd0355c212b14fd4cf375ce3a90f3d669fb182b (patch) | |
tree | ac764505b093420fda0f775ab7fc91c1370ec4bb | |
parent | 0ee1cdab7e5896d56c7c6d9681a427e386fa2ae9 (diff) |
Cycles: Try to avoid infinite loops by catching invalid ray states
-rw-r--r-- | intern/cycles/device/device.h | 8 | ||||
-rw-r--r-- | intern/cycles/device/device_split_kernel.cpp | 11 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 15 |
3 files changed, 25 insertions, 9 deletions
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 18e8e274172..ec15a254f81 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -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 */ diff --git a/intern/cycles/device/device_split_kernel.cpp b/intern/cycles/device/device_split_kernel.cpp index 5b892038ebb..8925ef47b2e 100644 --- a/intern/cycles/device/device_split_kernel.cpp +++ b/intern/cycles/device/device_split_kernel.cpp @@ -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; diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index f2ba3586c22..b6b891627bf 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -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. */ |