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:
authorMai Lavelle <mai.lavelle@gmail.com>2017-03-11 15:03:17 +0300
committerMai Lavelle <mai.lavelle@gmail.com>2017-03-14 13:22:57 +0300
commit8dd0355c212b14fd4cf375ce3a90f3d669fb182b (patch)
treeac764505b093420fda0f775ab7fc91c1370ec4bb
parent0ee1cdab7e5896d56c7c6d9681a427e386fa2ae9 (diff)
Cycles: Try to avoid infinite loops by catching invalid ray states
-rw-r--r--intern/cycles/device/device.h8
-rw-r--r--intern/cycles/device/device_split_kernel.cpp11
-rw-r--r--intern/cycles/kernel/kernel_types.h15
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. */