From 0509553b5eb240b3970848a4432e0bbfcbba8690 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 29 Mar 2014 13:03:46 +0100 Subject: Cycles code refactor: changes to make adding new primitive types easier. --- intern/cycles/kernel/geom/geom_bvh_subsurface.h | 22 +++++++++------ intern/cycles/kernel/geom/geom_bvh_traversal.h | 37 +++++++++++++++---------- intern/cycles/kernel/geom/geom_curve.h | 24 ++++++++-------- intern/cycles/kernel/geom/geom_triangle.h | 2 ++ 4 files changed, 51 insertions(+), 34 deletions(-) (limited to 'intern/cycles/kernel/geom') diff --git a/intern/cycles/kernel/geom/geom_bvh_subsurface.h b/intern/cycles/kernel/geom/geom_bvh_subsurface.h index 6529f58c0d2..d61929405ef 100644 --- a/intern/cycles/kernel/geom/geom_bvh_subsurface.h +++ b/intern/cycles/kernel/geom/geom_bvh_subsurface.h @@ -204,19 +204,23 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio /* primitive intersection */ for(; primAddr < primAddr2; primAddr++) { -#if FEATURE(BVH_HAIR) - uint segment = kernel_tex_fetch(__prim_segment, primAddr); - if(segment != ~0) - continue; -#endif - /* only primitives from the same object */ uint tri_object = (object == ~0)? kernel_tex_fetch(__prim_object, primAddr): object; - if(tri_object == subsurface_object) { + if(tri_object != subsurface_object) + continue; - /* intersect ray against primitive */ - triangle_intersect_subsurface(kg, isect_array, P, idir, object, primAddr, isect_t, &num_hits, lcg_state, max_hits); + /* intersect ray against primitive */ + uint type = kernel_tex_fetch(__prim_type, primAddr); + + switch(type & PRIMITIVE_ALL) { + case PRIMITIVE_TRIANGLE: { + triangle_intersect_subsurface(kg, isect_array, P, idir, object, primAddr, isect_t, &num_hits, lcg_state, max_hits); + break; + } + default: { + break; + } } } } diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h index 3a50ffedfde..1abefb51976 100644 --- a/intern/cycles/kernel/geom/geom_bvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h @@ -249,26 +249,35 @@ ccl_device bool BVH_FUNCTION_NAME /* primitive intersection */ while(primAddr < primAddr2) { bool hit; + uint type = kernel_tex_fetch(__prim_type, primAddr); - /* intersect ray against primitive */ + switch(type & PRIMITIVE_ALL) { + case PRIMITIVE_TRIANGLE: { + hit = triangle_intersect(kg, isect, P, idir, visibility, object, primAddr); + break; + } #if FEATURE(BVH_HAIR) - uint segment = kernel_tex_fetch(__prim_segment, primAddr); - if(segment != ~0) { - - if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) + case PRIMITIVE_CURVE: { #if FEATURE(BVH_HAIR_MINIMUM_WIDTH) - hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, segment, lcg_state, difl, extmax); - else - hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, segment, lcg_state, difl, extmax); + if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) + hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax); + else + hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax); #else - hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, segment); - else - hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, segment); + if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) + hit = bvh_cardinal_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, type); + else + hit = bvh_curve_intersect(kg, isect, P, idir, visibility, object, primAddr, ray->time, type); #endif - } - else + + break; + } #endif - hit = triangle_intersect(kg, isect, P, idir, visibility, object, primAddr); + default: { + hit = false; + break; + } + } /* shadow ray early termination */ #if defined(__KERNEL_SSE2__) diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h index ec9081a6c75..484f3ae6eb9 100644 --- a/intern/cycles/kernel/geom/geom_curve.h +++ b/intern/cycles/kernel/geom/geom_curve.h @@ -30,7 +30,7 @@ ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, } else if(elem == ATTR_ELEMENT_CURVE_KEY || elem == ATTR_ELEMENT_CURVE_KEY_MOTION) { float4 curvedata = kernel_tex_fetch(__curves, sd->prim); - int k0 = __float_as_int(curvedata.x) + sd->segment; + int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); int k1 = k0 + 1; float f0 = kernel_tex_fetch(__attributes_float, offset + k0); @@ -69,7 +69,7 @@ ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd } else if(elem == ATTR_ELEMENT_CURVE_KEY || elem == ATTR_ELEMENT_CURVE_KEY_MOTION) { float4 curvedata = kernel_tex_fetch(__curves, sd->prim); - int k0 = __float_as_int(curvedata.x) + sd->segment; + int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); int k1 = k0 + 1; float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0)); @@ -98,9 +98,9 @@ ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd) { float r = 0.0f; - if(sd->segment != ~0) { + if(sd->type & PRIMITIVE_ALL_CURVE) { float4 curvedata = kernel_tex_fetch(__curves, sd->prim); - int k0 = __float_as_int(curvedata.x) + sd->segment; + int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); int k1 = k0 + 1; float4 P1 = kernel_tex_fetch(__curve_keys, k0); @@ -115,7 +115,7 @@ ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd) { float3 tgN = make_float3(0.0f,0.0f,0.0f); - if(sd->segment != ~0) { + if(sd->type & PRIMITIVE_ALL_CURVE) { tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) / len_squared(sd->dPdu))); tgN = normalize(tgN); @@ -192,12 +192,13 @@ ccl_device_inline __m128 transform_point_T3(const __m128 t[3], const __m128 &a) #ifdef __KERNEL_SSE2__ /* Pass P and idir by reference to aligned vector */ ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect, - const float3 &P, const float3 &idir, uint visibility, int object, int curveAddr, float time, int segment, uint *lcg_state, float difl, float extmax) + const float3 &P, const float3 &idir, uint visibility, int object, int curveAddr, float time, int type, uint *lcg_state, float difl, float extmax) #else ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect, - float3 P, float3 idir, uint visibility, int object, int curveAddr, float time, int segment, uint *lcg_state, float difl, float extmax) + float3 P, float3 idir, uint visibility, int object, int curveAddr, float time,int type, uint *lcg_state, float difl, float extmax) #endif { + int segment = PRIMITIVE_UNPACK_SEGMENT(type); float epsilon = 0.0f; float r_st, r_en; @@ -548,7 +549,7 @@ ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersect /* record intersection */ isect->prim = curveAddr; isect->object = object; - isect->segment = segment; + isect->type = type; isect->u = u; isect->v = 0.0f; /*isect->v = 1.0f - coverage; */ @@ -569,7 +570,7 @@ ccl_device_inline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersect } ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isect, - float3 P, float3 idir, uint visibility, int object, int curveAddr, float time, int segment, uint *lcg_state, float difl, float extmax) + float3 P, float3 idir, uint visibility, int object, int curveAddr, float time, int type, uint *lcg_state, float difl, float extmax) { /* define few macros to minimize code duplication for SSE */ #ifndef __KERNEL_SSE2__ @@ -578,6 +579,7 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec #define dot3(x, y) dot(x, y) #endif + int segment = PRIMITIVE_UNPACK_SEGMENT(type); /* curve Intersection check */ int flags = kernel_data.curve.curveflags; @@ -768,7 +770,7 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec /* record intersection */ isect->prim = curveAddr; isect->object = object; - isect->segment = segment; + isect->type = type; isect->u = z*invl; isect->v = td/(4*a*a); /*isect->v = 1.0f - adjradius;*/ @@ -841,7 +843,7 @@ ccl_device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, con int prim = kernel_tex_fetch(__prim_index, isect->prim); float4 v00 = kernel_tex_fetch(__curves, prim); - int k0 = __float_as_int(v00.x) + sd->segment; + int k0 = __float_as_int(v00.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); int k1 = k0 + 1; float3 tg; diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h index 1bdc76445f9..7b115daa022 100644 --- a/intern/cycles/kernel/geom/geom_triangle.h +++ b/intern/cycles/kernel/geom/geom_triangle.h @@ -290,6 +290,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, Intersection *isect /* record intersection */ isect->prim = triAddr; isect->object = object; + isect->type = PRIMITIVE_TRIANGLE; isect->u = u; isect->v = v; isect->t = t; @@ -353,6 +354,7 @@ ccl_device_inline void triangle_intersect_subsurface(KernelGlobals *kg, Intersec Intersection *isect = &isect_array[hit]; isect->prim = triAddr; isect->object = object; + isect->type = PRIMITIVE_TRIANGLE; isect->u = u; isect->v = v; isect->t = t; -- cgit v1.2.3