diff options
Diffstat (limited to 'intern/cycles/util/util_atomic.h')
-rw-r--r-- | intern/cycles/util/util_atomic.h | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/intern/cycles/util/util_atomic.h b/intern/cycles/util/util_atomic.h index 7bbd97b8667..1d1e2963348 100644 --- a/intern/cycles/util/util_atomic.h +++ b/intern/cycles/util/util_atomic.h @@ -17,17 +17,49 @@ #ifndef __UTIL_ATOMIC_H__ #define __UTIL_ATOMIC_H__ +#ifndef __KERNEL_GPU__ + /* Using atomic ops header from Blender. */ #include "atomic_ops.h" ATOMIC_INLINE void atomic_update_max_z(size_t *maximum_value, size_t value) { size_t prev_value = *maximum_value; - while (prev_value < value) { - if (atomic_cas_z(maximum_value, prev_value, value) != prev_value) { + while(prev_value < value) { + if(atomic_cas_z(maximum_value, prev_value, value) != prev_value) { break; } } } +#else /* __KERNEL_GPU__ */ + +#ifdef __KERNEL_OPENCL__ + +/* Float atomics implementation credits: + * http://suhorukov.blogspot.in/2011/12/opencl-11-atomic-operations-on-floating.html + */ +ccl_device_inline void atomic_add_float(volatile ccl_global float *source, + const float operand) +{ + union { + unsigned int int_value; + float float_value; + } new_value; + union { + unsigned int int_value; + float float_value; + } prev_value; + do { + prev_value.float_value = *source; + new_value.float_value = prev_value.float_value + operand; + } while(atomic_cmpxchg((volatile ccl_global unsigned int *)source, + prev_value.int_value, + new_value.int_value) != prev_value.int_value); +} + +#endif /* __KERNEL_OPENCL__ */ + +#endif /* __KERNEL_GPU__ */ + #endif /* __UTIL_ATOMIC_H__ */ |