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:
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_subsurface.h22
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_traversal.h37
-rw-r--r--intern/cycles/kernel/geom/geom_curve.h24
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h2
-rw-r--r--intern/cycles/kernel/kernel_emission.h9
-rw-r--r--intern/cycles/kernel/kernel_primitive.h8
-rw-r--r--intern/cycles/kernel/kernel_shader.h117
-rw-r--r--intern/cycles/kernel/kernel_textures.h2
-rw-r--r--intern/cycles/kernel/kernel_types.h30
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp17
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp2
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h2
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h4
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h2
-rw-r--r--intern/cycles/kernel/svm/svm_wireframe.h2
15 files changed, 139 insertions, 141 deletions
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__
@@ -320,8 +291,14 @@ ccl_device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
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