diff options
Diffstat (limited to 'intern/cycles/kernel/geom/geom_motion_curve.h')
-rw-r--r-- | intern/cycles/kernel/geom/geom_motion_curve.h | 306 |
1 files changed, 159 insertions, 147 deletions
diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h b/intern/cycles/kernel/geom/geom_motion_curve.h index 5cc22ae2155..7380c506bf4 100644 --- a/intern/cycles/kernel/geom/geom_motion_curve.h +++ b/intern/cycles/kernel/geom/geom_motion_curve.h @@ -25,96 +25,116 @@ CCL_NAMESPACE_BEGIN #ifdef __HAIR__ -ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem) +ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg, + int object, + uint id, + AttributeElement *elem) { - /* todo: find a better (faster) solution for this, maybe store offset per object. - * - * NOTE: currently it's not a bottleneck because in test scenes the loop below runs - * zero iterations and rendering is really slow with motion curves. For until other - * areas are speed up it's probably not so crucial to optimize this out. - */ - uint attr_offset = object_attribute_map_offset(kg, object) + ATTR_PRIM_CURVE; - uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); - - while(attr_map.x != id) { - attr_offset += ATTR_PRIM_TYPES; - attr_map = kernel_tex_fetch(__attributes_map, attr_offset); - } - - *elem = (AttributeElement)attr_map.y; - - /* return result */ - return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z; + /* todo: find a better (faster) solution for this, maybe store offset per object. + * + * NOTE: currently it's not a bottleneck because in test scenes the loop below runs + * zero iterations and rendering is really slow with motion curves. For until other + * areas are speed up it's probably not so crucial to optimize this out. + */ + uint attr_offset = object_attribute_map_offset(kg, object) + ATTR_PRIM_CURVE; + uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); + + while (attr_map.x != id) { + attr_offset += ATTR_PRIM_TYPES; + attr_map = kernel_tex_fetch(__attributes_map, attr_offset); + } + + *elem = (AttributeElement)attr_map.y; + + /* return result */ + return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z; } -ccl_device_inline void motion_curve_keys_for_step(KernelGlobals *kg, int offset, int numkeys, int numsteps, int step, int k0, int k1, float4 keys[2]) +ccl_device_inline void motion_curve_keys_for_step(KernelGlobals *kg, + int offset, + int numkeys, + int numsteps, + int step, + int k0, + int k1, + float4 keys[2]) { - if(step == numsteps) { - /* center step: regular key location */ - keys[0] = kernel_tex_fetch(__curve_keys, k0); - keys[1] = kernel_tex_fetch(__curve_keys, k1); - } - else { - /* center step is not stored in this array */ - if(step > numsteps) - step--; - - offset += step*numkeys; - - keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0); - keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1); - } + if (step == numsteps) { + /* center step: regular key location */ + keys[0] = kernel_tex_fetch(__curve_keys, k0); + keys[1] = kernel_tex_fetch(__curve_keys, k1); + } + else { + /* center step is not stored in this array */ + if (step > numsteps) + step--; + + offset += step * numkeys; + + keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0); + keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1); + } } /* return 2 curve key locations */ -ccl_device_inline void motion_curve_keys(KernelGlobals *kg, int object, int prim, float time, int k0, int k1, float4 keys[2]) +ccl_device_inline void motion_curve_keys( + KernelGlobals *kg, int object, int prim, float time, int k0, int k1, float4 keys[2]) { - /* get motion info */ - int numsteps, numkeys; - object_motion_info(kg, object, &numsteps, NULL, &numkeys); + /* get motion info */ + int numsteps, numkeys; + object_motion_info(kg, object, &numsteps, NULL, &numkeys); - /* figure out which steps we need to fetch and their interpolation factor */ - int maxstep = numsteps*2; - int step = min((int)(time*maxstep), maxstep-1); - float t = time*maxstep - step; + /* figure out which steps we need to fetch and their interpolation factor */ + int maxstep = numsteps * 2; + int step = min((int)(time * maxstep), maxstep - 1); + float t = time * maxstep - step; - /* find attribute */ - AttributeElement elem; - int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem); - kernel_assert(offset != ATTR_STD_NOT_FOUND); + /* find attribute */ + AttributeElement elem; + int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem); + kernel_assert(offset != ATTR_STD_NOT_FOUND); - /* fetch key coordinates */ - float4 next_keys[2]; + /* fetch key coordinates */ + float4 next_keys[2]; - motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, keys); - motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step+1, k0, k1, next_keys); + motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, keys); + motion_curve_keys_for_step(kg, offset, numkeys, numsteps, step + 1, k0, k1, next_keys); - /* interpolate between steps */ - keys[0] = (1.0f - t)*keys[0] + t*next_keys[0]; - keys[1] = (1.0f - t)*keys[1] + t*next_keys[1]; + /* interpolate between steps */ + keys[0] = (1.0f - t) * keys[0] + t * next_keys[0]; + keys[1] = (1.0f - t) * keys[1] + t * next_keys[1]; } -ccl_device_inline void motion_cardinal_curve_keys_for_step(KernelGlobals *kg, int offset, int numkeys, int numsteps, int step, int k0, int k1, int k2, int k3, float4 keys[4]) +ccl_device_inline void motion_cardinal_curve_keys_for_step(KernelGlobals *kg, + int offset, + int numkeys, + int numsteps, + int step, + int k0, + int k1, + int k2, + int k3, + float4 keys[4]) { - if(step == numsteps) { - /* center step: regular key location */ - keys[0] = kernel_tex_fetch(__curve_keys, k0); - keys[1] = kernel_tex_fetch(__curve_keys, k1); - keys[2] = kernel_tex_fetch(__curve_keys, k2); - keys[3] = kernel_tex_fetch(__curve_keys, k3); - } - else { - /* center step is not stored in this array */ - if(step > numsteps) - step--; - - offset += step*numkeys; - - keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0); - keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1); - keys[2] = kernel_tex_fetch(__attributes_float3, offset + k2); - keys[3] = kernel_tex_fetch(__attributes_float3, offset + k3); - } + if (step == numsteps) { + /* center step: regular key location */ + keys[0] = kernel_tex_fetch(__curve_keys, k0); + keys[1] = kernel_tex_fetch(__curve_keys, k1); + keys[2] = kernel_tex_fetch(__curve_keys, k2); + keys[3] = kernel_tex_fetch(__curve_keys, k3); + } + else { + /* center step is not stored in this array */ + if (step > numsteps) + step--; + + offset += step * numkeys; + + keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0); + keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1); + keys[2] = kernel_tex_fetch(__attributes_float3, offset + k2); + keys[3] = kernel_tex_fetch(__attributes_float3, offset + k3); + } } /* return 2 curve key locations */ @@ -122,37 +142,41 @@ ccl_device_inline void motion_cardinal_curve_keys(KernelGlobals *kg, int object, int prim, float time, - int k0, int k1, int k2, int k3, + int k0, + int k1, + int k2, + int k3, float4 keys[4]) { - /* get motion info */ - int numsteps, numkeys; - object_motion_info(kg, object, &numsteps, NULL, &numkeys); - - /* figure out which steps we need to fetch and their interpolation factor */ - int maxstep = numsteps*2; - int step = min((int)(time*maxstep), maxstep-1); - float t = time*maxstep - step; - - /* find attribute */ - AttributeElement elem; - int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem); - kernel_assert(offset != ATTR_STD_NOT_FOUND); - - /* fetch key coordinates */ - float4 next_keys[4]; - - motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, k2, k3, keys); - motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step+1, k0, k1, k2, k3, next_keys); - - /* interpolate between steps */ - keys[0] = (1.0f - t)*keys[0] + t*next_keys[0]; - keys[1] = (1.0f - t)*keys[1] + t*next_keys[1]; - keys[2] = (1.0f - t)*keys[2] + t*next_keys[2]; - keys[3] = (1.0f - t)*keys[3] + t*next_keys[3]; + /* get motion info */ + int numsteps, numkeys; + object_motion_info(kg, object, &numsteps, NULL, &numkeys); + + /* figure out which steps we need to fetch and their interpolation factor */ + int maxstep = numsteps * 2; + int step = min((int)(time * maxstep), maxstep - 1); + float t = time * maxstep - step; + + /* find attribute */ + AttributeElement elem; + int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem); + kernel_assert(offset != ATTR_STD_NOT_FOUND); + + /* fetch key coordinates */ + float4 next_keys[4]; + + motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, k2, k3, keys); + motion_cardinal_curve_keys_for_step( + kg, offset, numkeys, numsteps, step + 1, k0, k1, k2, k3, next_keys); + + /* interpolate between steps */ + keys[0] = (1.0f - t) * keys[0] + t * next_keys[0]; + keys[1] = (1.0f - t) * keys[1] + t * next_keys[1]; + keys[2] = (1.0f - t) * keys[2] + t * next_keys[2]; + keys[3] = (1.0f - t) * keys[3] + t * next_keys[3]; } -#if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) +# if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) /* Similar to above, but returns keys as pair of two AVX registers with each * holding two float4. */ @@ -160,56 +184,44 @@ ccl_device_inline void motion_cardinal_curve_keys_avx(KernelGlobals *kg, int object, int prim, float time, - int k0, int k1, - int k2, int k3, + int k0, + int k1, + int k2, + int k3, avxf *out_keys_0_1, avxf *out_keys_2_3) { - /* Get motion info. */ - int numsteps, numkeys; - object_motion_info(kg, object, &numsteps, NULL, &numkeys); - - /* Figure out which steps we need to fetch and their interpolation factor. */ - int maxstep = numsteps * 2; - int step = min((int)(time*maxstep), maxstep - 1); - float t = time*maxstep - step; - - /* Find attribute. */ - AttributeElement elem; - int offset = find_attribute_curve_motion(kg, - object, - ATTR_STD_MOTION_VERTEX_POSITION, - &elem); - kernel_assert(offset != ATTR_STD_NOT_FOUND); - - /* Fetch key coordinates. */ - float4 next_keys[4]; - float4 keys[4]; - motion_cardinal_curve_keys_for_step(kg, - offset, - numkeys, - numsteps, - step, - k0, k1, k2, k3, - keys); - motion_cardinal_curve_keys_for_step(kg, - offset, - numkeys, - numsteps, - step + 1, - k0, k1, k2, k3, - next_keys); - - const avxf keys_0_1 = avxf(keys[0].m128, keys[1].m128); - const avxf keys_2_3 = avxf(keys[2].m128, keys[3].m128); - const avxf next_keys_0_1 = avxf(next_keys[0].m128, next_keys[1].m128); - const avxf next_keys_2_3 = avxf(next_keys[2].m128, next_keys[3].m128); - - /* Interpolate between steps. */ - *out_keys_0_1 = (1.0f - t) * keys_0_1 + t*next_keys_0_1; - *out_keys_2_3 = (1.0f - t) * keys_2_3 + t*next_keys_2_3; + /* Get motion info. */ + int numsteps, numkeys; + object_motion_info(kg, object, &numsteps, NULL, &numkeys); + + /* Figure out which steps we need to fetch and their interpolation factor. */ + int maxstep = numsteps * 2; + int step = min((int)(time * maxstep), maxstep - 1); + float t = time * maxstep - step; + + /* Find attribute. */ + AttributeElement elem; + int offset = find_attribute_curve_motion(kg, object, ATTR_STD_MOTION_VERTEX_POSITION, &elem); + kernel_assert(offset != ATTR_STD_NOT_FOUND); + + /* Fetch key coordinates. */ + float4 next_keys[4]; + float4 keys[4]; + motion_cardinal_curve_keys_for_step(kg, offset, numkeys, numsteps, step, k0, k1, k2, k3, keys); + motion_cardinal_curve_keys_for_step( + kg, offset, numkeys, numsteps, step + 1, k0, k1, k2, k3, next_keys); + + const avxf keys_0_1 = avxf(keys[0].m128, keys[1].m128); + const avxf keys_2_3 = avxf(keys[2].m128, keys[3].m128); + const avxf next_keys_0_1 = avxf(next_keys[0].m128, next_keys[1].m128); + const avxf next_keys_2_3 = avxf(next_keys[2].m128, next_keys[3].m128); + + /* Interpolate between steps. */ + *out_keys_0_1 = (1.0f - t) * keys_0_1 + t * next_keys_0_1; + *out_keys_2_3 = (1.0f - t) * keys_2_3 + t * next_keys_2_3; } -#endif +# endif #endif |