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 + intern/cycles/kernel/kernel_emission.h | 9 +- intern/cycles/kernel/kernel_primitive.h | 8 +- intern/cycles/kernel/kernel_shader.h | 117 ++++++++++-------------- intern/cycles/kernel/kernel_textures.h | 2 +- intern/cycles/kernel/kernel_types.h | 30 ++++-- intern/cycles/kernel/osl/osl_services.cpp | 17 ++-- intern/cycles/kernel/osl/osl_shader.cpp | 2 +- intern/cycles/kernel/svm/svm_attribute.h | 2 +- intern/cycles/kernel/svm/svm_closure.h | 4 +- intern/cycles/kernel/svm/svm_geometry.h | 2 +- intern/cycles/kernel/svm/svm_wireframe.h | 2 +- 15 files changed, 139 insertions(+), 141 deletions(-) (limited to 'intern/cycles/kernel') 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; diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index cbcec4291bd..44c2572efc2 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -43,12 +43,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando, else #endif { -#ifdef __HAIR__ - if(ls->type == LIGHT_STRAND) - shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ls->prim); - else -#endif - shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ~0); + shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1); ls->Ng = sd.Ng; @@ -171,7 +166,7 @@ ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, Shader float3 L = shader_emissive_eval(kg, sd); #ifdef __HAIR__ - if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->segment == ~0)) { + if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->type & PRIMITIVE_ALL_TRIANGLE)) { #else if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS)) { #endif diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/kernel_primitive.h index fa450c97cbf..f9efdd2cf56 100644 --- a/intern/cycles/kernel/kernel_primitive.h +++ b/intern/cycles/kernel/kernel_primitive.h @@ -36,7 +36,7 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, /* for SVM, find attribute by unique id */ uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride; #ifdef __HAIR__ - attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE; + attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset; #endif uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); @@ -58,7 +58,7 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy) { #ifdef __HAIR__ - if(sd->segment == ~0) + if(sd->type & PRIMITIVE_ALL_TRIANGLE) #endif return triangle_attribute_float(kg, sd, elem, offset, dx, dy); #ifdef __HAIR__ @@ -70,7 +70,7 @@ ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData * ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy) { #ifdef __HAIR__ - if(sd->segment == ~0) + if(sd->type & PRIMITIVE_ALL_TRIANGLE) #endif return triangle_attribute_float3(kg, sd, elem, offset, dx, dy); #ifdef __HAIR__ @@ -126,7 +126,7 @@ ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, in ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd) { #ifdef __HAIR__ - if(sd->segment != ~0) + if(sd->type & PRIMITIVE_ALL_CURVE) #ifdef __DPDU__ return normalize(sd->dPdu); #else diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 0f327f16419..95cdfd1a80a 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -55,6 +55,7 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object; #endif + sd->type = isect->type; sd->flag = kernel_tex_fetch(__object_flag, sd->object); /* matrices and time */ @@ -67,34 +68,27 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, sd->ray_length = isect->t; sd->ray_depth = bounce; +#ifdef __UV__ + sd->u = isect->u; + sd->v = isect->v; +#endif + #ifdef __HAIR__ - if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) { - /* Strand Shader setting*/ + if(sd->type & PRIMITIVE_ALL_CURVE) { + /* curve */ float4 curvedata = kernel_tex_fetch(__curves, sd->prim); sd->shader = __float_as_int(curvedata.z); - sd->segment = isect->segment; sd->P = bvh_curve_refine(kg, sd, isect, ray); } - else { + else #endif + { /* fetch triangle data */ float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim); float3 Ng = make_float3(Ns.x, Ns.y, Ns.z); sd->shader = __float_as_int(Ns.w); -#ifdef __HAIR__ - sd->segment = ~0; - /*elements for minimum hair width using transparency bsdf*/ - /*sd->curve_transparency = 0.0f;*/ - /*sd->curve_radius = 0.0f;*/ -#endif - -#ifdef __UV__ - sd->u = isect->u; - sd->v = isect->v; -#endif - /* vectors */ sd->P = triangle_refine(kg, sd, isect, ray); sd->Ng = Ng; @@ -108,10 +102,7 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, /* dPdu/dPdv */ triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv); #endif - -#ifdef __HAIR__ } -#endif sd->I = -ray->D; @@ -161,34 +152,32 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat /* object, matrices, time, ray_length stay the same */ sd->flag = kernel_tex_fetch(__object_flag, sd->object); sd->prim = kernel_tex_fetch(__prim_index, isect->prim); - - /* fetch triangle data */ - float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim); - float3 Ng = make_float3(Ns.x, Ns.y, Ns.z); - sd->shader = __float_as_int(Ns.w); - -#ifdef __HAIR__ - sd->segment = ~0; -#endif + sd->type = isect->type; #ifdef __UV__ sd->u = isect->u; sd->v = isect->v; #endif - /* vectors */ - sd->P = triangle_refine_subsurface(kg, sd, isect, ray); - sd->Ng = Ng; - sd->N = Ng; - - /* smooth normal */ - if(sd->shader & SHADER_SMOOTH_NORMAL) - sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); + /* fetch triangle data */ + { + float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim); + float3 Ng = make_float3(Ns.x, Ns.y, Ns.z); + sd->shader = __float_as_int(Ns.w); + + /* static triangle */ + sd->P = triangle_refine_subsurface(kg, sd, isect, ray); + sd->Ng = Ng; + sd->N = Ng; + + if(sd->shader & SHADER_SMOOTH_NORMAL) + sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); #ifdef __DPDU__ - /* dPdu/dPdv */ - triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv); + /* dPdu/dPdv */ + triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv); #endif + } sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); @@ -231,7 +220,7 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, const float3 P, const float3 Ng, const float3 I, - int shader, int object, int prim, float u, float v, float t, float time, int bounce, int segment) + int shader, int object, int prim, float u, float v, float t, float time, int bounce) { /* vectors */ sd->P = P; @@ -239,9 +228,7 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, sd->Ng = Ng; sd->I = I; sd->shader = shader; -#ifdef __HAIR__ - sd->segment = segment; -#endif + sd->type = (prim == ~0)? PRIMITIVE_NONE: PRIMITIVE_TRIANGLE; /* primitive */ #ifdef __INSTANCING__ @@ -283,35 +270,19 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, } #endif - /* smooth normal */ -#ifdef __HAIR__ - if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) { - sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); -#else - if(sd->shader & SHADER_SMOOTH_NORMAL) { - sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); -#endif + if(sd->type & PRIMITIVE_TRIANGLE) { + /* smooth normal */ + if(sd->shader & SHADER_SMOOTH_NORMAL) { + sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); #ifdef __INSTANCING__ - if(instanced) - object_normal_transform(kg, sd, &sd->N); + if(instanced) + object_normal_transform(kg, sd, &sd->N); #endif - } + } + /* dPdu/dPdv */ #ifdef __DPDU__ - /* dPdu/dPdv */ -#ifdef __HAIR__ - if(sd->prim == ~0 || sd->segment != ~0) { - sd->dPdu = make_float3(0.0f, 0.0f, 0.0f); - sd->dPdv = make_float3(0.0f, 0.0f, 0.0f); - } -#else - if(sd->prim == ~0) { - sd->dPdu = make_float3(0.0f, 0.0f, 0.0f); - sd->dPdv = make_float3(0.0f, 0.0f, 0.0f); - } -#endif - else { triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv); #ifdef __INSTANCING__ @@ -319,9 +290,15 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, object_dir_transform(kg, sd, &sd->dPdu); object_dir_transform(kg, sd, &sd->dPdv); } +#endif #endif } + else { +#ifdef __DPDU__ + sd->dPdu = make_float3(0.0f, 0.0f, 0.0f); + sd->dPdv = make_float3(0.0f, 0.0f, 0.0f); #endif + } /* backfacing test */ if(sd->prim != ~0) { @@ -362,7 +339,7 @@ ccl_device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd, /* watch out: no instance transform currently */ - shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0, ~0); + shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, 0); } /* ShaderData setup from ray into background */ @@ -429,9 +406,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s sd->object = ~0; /* todo: fill this for texture coordinates */ #endif sd->prim = ~0; -#ifdef __HAIR__ - sd->segment = ~0; -#endif + sd->type = PRIMITIVE_NONE; #ifdef __UV__ sd->u = 0.0f; @@ -1146,7 +1121,7 @@ ccl_device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect int shader = 0; #ifdef __HAIR__ - if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) { + if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) { #endif float4 Ns = kernel_tex_fetch(__tri_normal, prim); shader = __float_as_int(Ns.w); diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h index f06fa119cfc..c8734d67c3b 100644 --- a/intern/cycles/kernel/kernel_textures.h +++ b/intern/cycles/kernel/kernel_textures.h @@ -25,7 +25,7 @@ /* bvh */ KERNEL_TEX(float4, texture_float4, __bvh_nodes) KERNEL_TEX(float4, texture_float4, __tri_woop) -KERNEL_TEX(uint, texture_uint, __prim_segment) +KERNEL_TEX(uint, texture_uint, __prim_type) KERNEL_TEX(uint, texture_uint, __prim_visibility) KERNEL_TEX(uint, texture_uint, __prim_index) KERNEL_TEX(uint, texture_uint, __prim_object) diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 70fafdfec92..b260a3d11ac 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -420,9 +420,27 @@ typedef struct Intersection { float t, u, v; int prim; int object; - int segment; + int type; } Intersection; +/* Primitives */ + +typedef enum PrimitiveType { + PRIMITIVE_NONE = 0, + PRIMITIVE_TRIANGLE = 1, + PRIMITIVE_MOTION_TRIANGLE = 2, + PRIMITIVE_CURVE = 4, + PRIMITIVE_MOTION_CURVE = 8, + + PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE|PRIMITIVE_MOTION_TRIANGLE), + PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE|PRIMITIVE_MOTION_CURVE), + PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE|PRIMITIVE_MOTION_CURVE), + PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE|PRIMITIVE_ALL_CURVE) +} PrimitiveType; + +#define PRIMITIVE_PACK_SEGMENT(type, segment) ((segment << 16) | type) +#define PRIMITIVE_UNPACK_SEGMENT(type) (type >> 16) + /* Attributes */ #define ATTR_PRIM_TYPES 2 @@ -565,13 +583,9 @@ typedef struct ShaderData { /* primitive id if there is one, ~0 otherwise */ int prim; -#ifdef __HAIR__ - /* for curves, segment number in curve, ~0 for triangles */ - int segment; - /* variables for minimum hair width using transparency bsdf */ - /*float curve_transparency; */ - /*float curve_radius; */ -#endif + /* combined type and curve segment for hair */ + int type; + /* parametric coordinates * - barycentric weights for triangles */ float u, v; diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index a25d2fe03b5..6768114e5fd 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -643,7 +643,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD } else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices) #ifdef __HAIR__ - && sd->segment == ~0) { + && sd->type & PRIMITIVE_ALL_TRIANGLE) { #else ) { #endif @@ -669,7 +669,7 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD #ifdef __HAIR__ /* Hair Attributes */ else if (name == u_is_curve) { - float f = (sd->segment != ~0); + float f = (sd->type & PRIMITIVE_ALL_CURVE) != 0; return set_attribute_float(f, type, derivatives, val); } else if (name == u_curve_thickness) { @@ -732,7 +732,8 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri { ShaderData *sd = (ShaderData *)renderstate; KernelGlobals *kg = sd->osl_globals; - int object, prim, segment; + bool is_curve; + int object, prim; /* lookup of attribute on another object */ if (object_name != u_empty) { @@ -743,23 +744,19 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri object = it->second; prim = ~0; - segment = ~0; + is_curve = false; } else { object = sd->object; prim = sd->prim; -#ifdef __HAIR__ - segment = sd->segment; -#else - segment = ~0; -#endif + is_curve = (sd->type & PRIMITIVE_ALL_CURVE) != 0; if (object == ~0) return get_background_attribute(kg, sd, name, type, derivatives, val); } /* find attribute on object */ - object = object*ATTR_PRIM_TYPES + (segment != ~0); + object = object*ATTR_PRIM_TYPES + (is_curve == true); OSLGlobals::AttributeMap& attribute_map = kg->osl->attribute_map[object]; OSLGlobals::AttributeMap::iterator it = attribute_map.find(name); diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 34d9ebefdb3..b5842d1013e 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -536,7 +536,7 @@ int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, /* for OSL, a hash map is used to lookup the attribute by name. */ int object = sd->object*ATTR_PRIM_TYPES; #ifdef __HAIR__ - if(sd->segment != ~0) object += ATTR_PRIM_CURVE; + if(sd->type & PRIMITIVE_ALL_CURVE) object += ATTR_PRIM_CURVE; #endif OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object]; diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h index 4c53bfd74fa..aae52ec3d84 100644 --- a/intern/cycles/kernel/svm/svm_attribute.h +++ b/intern/cycles/kernel/svm/svm_attribute.h @@ -27,7 +27,7 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, uint id = node.y; uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride; #ifdef __HAIR__ - attr_offset = (sd->segment == ~0)? attr_offset: attr_offset + ATTR_PRIM_CURVE; + attr_offset = (sd->type & PRIMITIVE_ALL_TRIANGLE)? attr_offset: attr_offset + ATTR_PRIM_CURVE; #endif uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 2813e38d8f7..49d99ead03e 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -364,7 +364,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * case CLOSURE_BSDF_HAIR_REFLECTION_ID: case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: { - if(sd->flag & SD_BACKFACING && sd->segment != ~0) { + if(sd->flag & SD_BACKFACING && sd->type & PRIMITIVE_ALL_CURVE) { ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight); if(sc) { sc->weight = make_float3(1.0f,1.0f,1.0f); @@ -381,7 +381,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * sc->data0 = param1; sc->data1 = param2; sc->offset = -stack_load_float(stack, data_node.z); - if(sd->segment == ~0) { + if(sd->type & PRIMITIVE_ALL_CURVE) { sc->T = normalize(sd->dPdv); sc->offset = 0.0f; } diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index ad0cacb027a..1ed6a4b1916 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -153,7 +153,7 @@ ccl_device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *sta switch(type) { case NODE_INFO_CURVE_IS_STRAND: { - data = (sd->segment != ~0); + data = (sd->type & PRIMITIVE_ALL_CURVE) != 0; stack_store_float(stack, out_offset, data); break; } diff --git a/intern/cycles/kernel/svm/svm_wireframe.h b/intern/cycles/kernel/svm/svm_wireframe.h index e560e6303cc..a20dcfa3fae 100644 --- a/intern/cycles/kernel/svm/svm_wireframe.h +++ b/intern/cycles/kernel/svm/svm_wireframe.h @@ -45,7 +45,7 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta /* Calculate wireframe */ #ifdef __HAIR__ - if (sd->prim != ~0 && sd->segment == ~0) { + if (sd->prim != ~0 && sd->type & PRIMITIVE_ALL_TRIANGLE) { #else if (sd->prim != ~0) { #endif -- cgit v1.2.3