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 /intern/cycles/device | |
parent | 0ee1cdab7e5896d56c7c6d9681a427e386fa2ae9 (diff) |
Cycles: Try to avoid infinite loops by catching invalid ray states
Diffstat (limited to 'intern/cycles/device')
-rw-r--r-- | intern/cycles/device/device.h | 8 | ||||
-rw-r--r-- | intern/cycles/device/device_split_kernel.cpp | 11 |
2 files changed, 18 insertions, 1 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; |