diff options
author | Mai Lavelle <mai.lavelle@gmail.com> | 2016-07-02 00:36:27 +0300 |
---|---|---|
committer | Mai Lavelle <mai.lavelle@gmail.com> | 2016-08-06 06:49:21 +0300 |
commit | cd809b95d828677468298f1eba54fc52bbb9db60 (patch) | |
tree | eb6830d04eb2388f8fa0c7a34f65ee5448e0ec87 /intern | |
parent | 734e0aca3872410dcaaf351e091a49a8d6186de2 (diff) |
Cycles: Add AttributeDescriptor
Adds a descriptor for attributes that can easily be passed around and extended
to contain more data. Will be used for attributes on subdivision meshes.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D2110
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/kernel/geom/geom_attribute.h | 38 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_curve.h | 24 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_primitive.h | 65 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_subd_triangle.h | 62 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_triangle.h | 38 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_volume.h | 27 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_globals.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_shader.cpp | 17 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_shader.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_attribute.h | 97 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_tex_coord.h | 29 | ||||
-rw-r--r-- | intern/cycles/render/attribute.cpp | 30 | ||||
-rw-r--r-- | intern/cycles/render/attribute.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 52 |
16 files changed, 248 insertions, 253 deletions
diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h index 5d78cf8f9fc..e036c2752d7 100644 --- a/intern/cycles/kernel/geom/geom_attribute.h +++ b/intern/cycles/kernel/geom/geom_attribute.h @@ -43,12 +43,19 @@ ccl_device_inline uint attribute_primitive_type(KernelGlobals *kg, const ShaderD } } +ccl_device_inline AttributeDescriptor attribute_not_found() +{ + const AttributeDescriptor desc = {ATTR_ELEMENT_NONE, (NodeAttributeType)0, ATTR_STD_NOT_FOUND}; + return desc; +} + /* Find attribute based on ID */ -ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem) +ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id) { - if(ccl_fetch(sd, object) == PRIM_NONE) - return (int)ATTR_STD_NOT_FOUND; + if(ccl_fetch(sd, object) == PRIM_NONE) { + return attribute_not_found(); + } /* for SVM, find attribute by unique id */ uint attr_offset = ccl_fetch(sd, object)*kernel_data.bvh.attributes_map_stride; @@ -57,31 +64,36 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, ui while(attr_map.x != id) { if(UNLIKELY(attr_map.x == ATTR_STD_NONE)) { - return ATTR_STD_NOT_FOUND; + return attribute_not_found(); } attr_offset += ATTR_PRIM_TYPES; attr_map = kernel_tex_fetch(__attributes_map, attr_offset); } - *elem = (AttributeElement)attr_map.y; + AttributeDescriptor desc; + desc.element = (AttributeElement)attr_map.y; - if(ccl_fetch(sd, prim) == PRIM_NONE && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH) - return ATTR_STD_NOT_FOUND; + if(ccl_fetch(sd, prim) == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH) { + return attribute_not_found(); + } /* return result */ - return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z; + desc.offset = (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z; + desc.type = (NodeAttributeType)attr_map.w; + + return desc; } /* Transform matrix attribute on meshes */ -ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset) +ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc) { Transform tfm; - tfm.x = kernel_tex_fetch(__attributes_float3, offset + 0); - tfm.y = kernel_tex_fetch(__attributes_float3, offset + 1); - tfm.z = kernel_tex_fetch(__attributes_float3, offset + 2); - tfm.w = kernel_tex_fetch(__attributes_float3, offset + 3); + tfm.x = kernel_tex_fetch(__attributes_float3, desc.offset + 0); + tfm.y = kernel_tex_fetch(__attributes_float3, desc.offset + 1); + tfm.z = kernel_tex_fetch(__attributes_float3, desc.offset + 2); + tfm.w = kernel_tex_fetch(__attributes_float3, desc.offset + 3); return tfm; } diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h index 292e1bfca0e..aa9cd295452 100644 --- a/intern/cycles/kernel/geom/geom_curve.h +++ b/intern/cycles/kernel/geom/geom_curve.h @@ -24,23 +24,23 @@ CCL_NAMESPACE_BEGIN /* Reading attributes on various curve elements */ -ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy) +ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy) { - if(elem == ATTR_ELEMENT_CURVE) { + if(desc.element == ATTR_ELEMENT_CURVE) { #ifdef __RAY_DIFFERENTIALS__ if(dx) *dx = 0.0f; if(dy) *dy = 0.0f; #endif - return kernel_tex_fetch(__attributes_float, offset + ccl_fetch(sd, prim)); + return kernel_tex_fetch(__attributes_float, desc.offset + ccl_fetch(sd, prim)); } - else if(elem == ATTR_ELEMENT_CURVE_KEY || elem == ATTR_ELEMENT_CURVE_KEY_MOTION) { + else if(desc.element == ATTR_ELEMENT_CURVE_KEY || desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) { float4 curvedata = kernel_tex_fetch(__curves, ccl_fetch(sd, prim)); int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(ccl_fetch(sd, type)); int k1 = k0 + 1; - float f0 = kernel_tex_fetch(__attributes_float, offset + k0); - float f1 = kernel_tex_fetch(__attributes_float, offset + k1); + float f0 = kernel_tex_fetch(__attributes_float, desc.offset + k0); + float f1 = kernel_tex_fetch(__attributes_float, desc.offset + k1); #ifdef __RAY_DIFFERENTIALS__ if(dx) *dx = ccl_fetch(sd, du).dx*(f1 - f0); @@ -59,9 +59,9 @@ ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, } } -ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy) +ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy) { - if(elem == ATTR_ELEMENT_CURVE) { + if(desc.element == ATTR_ELEMENT_CURVE) { /* idea: we can't derive any useful differentials here, but for tiled * mipmap image caching it would be useful to avoid reading the highest * detail level always. maybe a derivative based on the hair density @@ -71,15 +71,15 @@ ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f); #endif - return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + ccl_fetch(sd, prim))); + return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + ccl_fetch(sd, prim))); } - else if(elem == ATTR_ELEMENT_CURVE_KEY || elem == ATTR_ELEMENT_CURVE_KEY_MOTION) { + else if(desc.element == ATTR_ELEMENT_CURVE_KEY || desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) { float4 curvedata = kernel_tex_fetch(__curves, ccl_fetch(sd, prim)); int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(ccl_fetch(sd, type)); int k1 = k0 + 1; - float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k0)); - float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + k1)); + float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k0)); + float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k1)); #ifdef __RAY_DIFFERENTIALS__ if(dx) *dx = ccl_fetch(sd, du).dx*(f1 - f0); diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h index b16f0c9a99b..4384c2093e9 100644 --- a/intern/cycles/kernel/geom/geom_primitive.h +++ b/intern/cycles/kernel/geom/geom_primitive.h @@ -25,24 +25,23 @@ CCL_NAMESPACE_BEGIN ccl_device_inline float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, - AttributeElement elem, - int offset, + const AttributeDescriptor desc, float *dx, float *dy) { if(ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE) { if(subd_triangle_patch(kg, sd) == ~0) - return triangle_attribute_float(kg, sd, elem, offset, dx, dy); + return triangle_attribute_float(kg, sd, desc, dx, dy); else - return subd_triangle_attribute_float(kg, sd, elem, offset, dx, dy); + return subd_triangle_attribute_float(kg, sd, desc, dx, dy); } #ifdef __HAIR__ else if(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE) { - return curve_attribute_float(kg, sd, elem, offset, dx, dy); + return curve_attribute_float(kg, sd, desc, dx, dy); } #endif #ifdef __VOLUME__ - else if(ccl_fetch(sd, object) != OBJECT_NONE && elem == ATTR_ELEMENT_VOXEL) { - return volume_attribute_float(kg, sd, elem, offset, dx, dy); + else if(ccl_fetch(sd, object) != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) { + return volume_attribute_float(kg, sd, desc, dx, dy); } #endif else { @@ -54,25 +53,23 @@ ccl_device_inline float primitive_attribute_float(KernelGlobals *kg, ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, - AttributeElement elem, - int offset, - float3 *dx, - float3 *dy) + const AttributeDescriptor desc, + float3 *dx, float3 *dy) { if(ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE) { if(subd_triangle_patch(kg, sd) == ~0) - return triangle_attribute_float3(kg, sd, elem, offset, dx, dy); + return triangle_attribute_float3(kg, sd, desc, dx, dy); else - return subd_triangle_attribute_float3(kg, sd, elem, offset, dx, dy); + return subd_triangle_attribute_float3(kg, sd, desc, dx, dy); } #ifdef __HAIR__ else if(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE) { - return curve_attribute_float3(kg, sd, elem, offset, dx, dy); + return curve_attribute_float3(kg, sd, desc, dx, dy); } #endif #ifdef __VOLUME__ - else if(ccl_fetch(sd, object) != OBJECT_NONE && elem == ATTR_ELEMENT_VOXEL) { - return volume_attribute_float3(kg, sd, elem, offset, dx, dy); + else if(ccl_fetch(sd, object) != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) { + return volume_attribute_float3(kg, sd, desc, dx, dy); } #endif else { @@ -86,13 +83,12 @@ ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg, ccl_device_inline float3 primitive_uv(KernelGlobals *kg, ShaderData *sd) { - AttributeElement elem_uv; - int offset_uv = find_attribute(kg, sd, ATTR_STD_UV, &elem_uv); + const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_UV); - if(offset_uv == ATTR_STD_NOT_FOUND) + if(desc.offset == ATTR_STD_NOT_FOUND) return make_float3(0.0f, 0.0f, 0.0f); - float3 uv = primitive_attribute_float3(kg, sd, elem_uv, offset_uv, NULL, NULL); + float3 uv = primitive_attribute_float3(kg, sd, desc, NULL, NULL); uv.z = 1.0f; return uv; } @@ -102,15 +98,14 @@ ccl_device_inline float3 primitive_uv(KernelGlobals *kg, ShaderData *sd) ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, int *face_id) { /* storing ptex data as attributes is not memory efficient but simple for tests */ - AttributeElement elem_face_id, elem_uv; - int offset_face_id = find_attribute(kg, sd, ATTR_STD_PTEX_FACE_ID, &elem_face_id); - int offset_uv = find_attribute(kg, sd, ATTR_STD_PTEX_UV, &elem_uv); + const AttributeDescriptor desc_face_id = find_attribute(kg, sd, ATTR_STD_PTEX_FACE_ID); + const AttributeDescriptor desc_uv = find_attribute(kg, sd, ATTR_STD_PTEX_UV); - if(offset_face_id == ATTR_STD_NOT_FOUND || offset_uv == ATTR_STD_NOT_FOUND) + if(desc_face_id.offset == ATTR_STD_NOT_FOUND || desc_uv.offset == ATTR_STD_NOT_FOUND) return false; - float3 uv3 = primitive_attribute_float3(kg, sd, elem_uv, offset_uv, NULL, NULL); - float face_id_f = primitive_attribute_float(kg, sd, elem_face_id, offset_face_id, NULL, NULL); + float3 uv3 = primitive_attribute_float3(kg, sd, desc_uv, NULL, NULL); + float face_id_f = primitive_attribute_float(kg, sd, desc_face_id, NULL, NULL); *uv = make_float2(uv3.x, uv3.y); *face_id = (int)face_id_f; @@ -132,11 +127,10 @@ ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd) #endif /* try to create spherical tangent from generated coordinates */ - AttributeElement attr_elem; - int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED, &attr_elem); + const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_GENERATED); - if(attr_offset != ATTR_STD_NOT_FOUND) { - float3 data = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL); + if(desc.offset != ATTR_STD_NOT_FOUND) { + float3 data = primitive_attribute_float3(kg, sd, desc, NULL, NULL); data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f); object_normal_transform(kg, sd, &data); return cross(ccl_fetch(sd, N), normalize(cross(data, ccl_fetch(sd, N)))); @@ -173,19 +167,18 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals *kg, ShaderData * float3 motion_pre = center, motion_post = center; /* deformation motion */ - AttributeElement elem; - int offset = find_attribute(kg, sd, ATTR_STD_MOTION_VERTEX_POSITION, &elem); + AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_MOTION_VERTEX_POSITION); - if(offset != ATTR_STD_NOT_FOUND) { + if(desc.offset != ATTR_STD_NOT_FOUND) { /* get motion info */ int numverts, numkeys; object_motion_info(kg, ccl_fetch(sd, object), NULL, &numverts, &numkeys); /* lookup attributes */ - int offset_next = (ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE)? offset + numverts: offset + numkeys; + motion_pre = primitive_attribute_float3(kg, sd, desc, NULL, NULL); - motion_pre = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL); - motion_post = primitive_attribute_float3(kg, sd, elem, offset_next, NULL, NULL); + desc.offset += (ccl_fetch(sd, type) & PRIMITIVE_ALL_TRIANGLE)? numverts: numkeys; + motion_post = primitive_attribute_float3(kg, sd, desc, NULL, NULL); #ifdef __HAIR__ if(is_curve_primitive && (ccl_fetch(sd, flag) & SD_OBJECT_HAS_VERTEX_MOTION) == 0) { diff --git a/intern/cycles/kernel/geom/geom_subd_triangle.h b/intern/cycles/kernel/geom/geom_subd_triangle.h index bf9be182345..79a2ce5cc70 100644 --- a/intern/cycles/kernel/geom/geom_subd_triangle.h +++ b/intern/cycles/kernel/geom/geom_subd_triangle.h @@ -97,27 +97,27 @@ ccl_device_inline void subd_triangle_patch_corners(KernelGlobals *kg, int patch, /* Reading attributes on various subdivision triangle elements */ -ccl_device float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy) +ccl_device float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy) { int patch = subd_triangle_patch(kg, sd); - if(elem == ATTR_ELEMENT_FACE) { + if(desc.element == ATTR_ELEMENT_FACE) { if(dx) *dx = 0.0f; if(dy) *dy = 0.0f; - return kernel_tex_fetch(__attributes_float, offset + subd_triangle_patch_face(kg, patch)); + return kernel_tex_fetch(__attributes_float, desc.offset + subd_triangle_patch_face(kg, patch)); } - else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) { + else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) { float2 uv[3]; subd_triangle_patch_uv(kg, sd, uv); uint4 v = subd_triangle_patch_indices(kg, patch); float a, b, c; - float f0 = kernel_tex_fetch(__attributes_float, offset + v.x); - float f1 = kernel_tex_fetch(__attributes_float, offset + v.y); - float f2 = kernel_tex_fetch(__attributes_float, offset + v.z); - float f3 = kernel_tex_fetch(__attributes_float, offset + v.w); + float f0 = kernel_tex_fetch(__attributes_float, desc.offset + v.x); + float f1 = kernel_tex_fetch(__attributes_float, desc.offset + v.y); + float f2 = kernel_tex_fetch(__attributes_float, desc.offset + v.z); + float f3 = kernel_tex_fetch(__attributes_float, desc.offset + v.w); if(subd_triangle_patch_num_corners(kg, patch) != 4) { f1 = (f1+f0)*0.5f; @@ -135,7 +135,7 @@ ccl_device float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderDa return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*c; } - else if(elem == ATTR_ELEMENT_CORNER) { + else if(desc.element == ATTR_ELEMENT_CORNER) { int corners[4]; subd_triangle_patch_corners(kg, patch, corners); @@ -144,10 +144,10 @@ ccl_device float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderDa float a, b, c; - float f0 = kernel_tex_fetch(__attributes_float, corners[0] + offset); - float f1 = kernel_tex_fetch(__attributes_float, corners[1] + offset); - float f2 = kernel_tex_fetch(__attributes_float, corners[2] + offset); - float f3 = kernel_tex_fetch(__attributes_float, corners[3] + offset); + float f0 = kernel_tex_fetch(__attributes_float, corners[0] + desc.offset); + float f1 = kernel_tex_fetch(__attributes_float, corners[1] + desc.offset); + float f2 = kernel_tex_fetch(__attributes_float, corners[2] + desc.offset); + float f3 = kernel_tex_fetch(__attributes_float, corners[3] + desc.offset); if(subd_triangle_patch_num_corners(kg, patch) != 4) { f1 = (f1+f0)*0.5f; @@ -173,27 +173,27 @@ ccl_device float subd_triangle_attribute_float(KernelGlobals *kg, const ShaderDa } } -ccl_device float3 subd_triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy) +ccl_device float3 subd_triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy) { int patch = subd_triangle_patch(kg, sd); - if(elem == ATTR_ELEMENT_FACE) { + if(desc.element == ATTR_ELEMENT_FACE) { if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f); if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f); - return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + subd_triangle_patch_face(kg, patch))); + return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + subd_triangle_patch_face(kg, patch))); } - else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) { + else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) { float2 uv[3]; subd_triangle_patch_uv(kg, sd, uv); uint4 v = subd_triangle_patch_indices(kg, patch); float3 a, b, c; - float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.x)); - float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.y)); - float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.z)); - float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + v.w)); + float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.x)); + float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.y)); + float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.z)); + float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.w)); if(subd_triangle_patch_num_corners(kg, patch) != 4) { f1 = (f1+f0)*0.5f; @@ -211,7 +211,7 @@ ccl_device float3 subd_triangle_attribute_float3(KernelGlobals *kg, const Shader return ccl_fetch(sd, u)*a + ccl_fetch(sd, v)*b + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*c; } - else if(elem == ATTR_ELEMENT_CORNER || elem == ATTR_ELEMENT_CORNER_BYTE) { + else if(desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) { int corners[4]; subd_triangle_patch_corners(kg, patch, corners); @@ -221,17 +221,17 @@ ccl_device float3 subd_triangle_attribute_float3(KernelGlobals *kg, const Shader float3 a, b, c; float3 f0, f1, f2, f3; - if(elem == ATTR_ELEMENT_CORNER) { - f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + offset)); - f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + offset)); - f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + offset)); - f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + offset)); + if(desc.element == ATTR_ELEMENT_CORNER) { + f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset)); + f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset)); + f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset)); + f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset)); } else { - f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + offset)); - f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + offset)); - f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + offset)); - f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + offset)); + f0 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset)); + f1 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset)); + f2 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset)); + f3 = color_byte_to_float(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset)); } if(subd_triangle_patch_num_corners(kg, patch) != 4) { diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h index 0c2351e1d1b..d3289d6572c 100644 --- a/intern/cycles/kernel/geom/geom_triangle.h +++ b/intern/cycles/kernel/geom/geom_triangle.h @@ -105,20 +105,20 @@ ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, int prim, ccl_addr_spa /* Reading attributes on various triangle elements */ -ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy) +ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy) { - if(elem == ATTR_ELEMENT_FACE) { + if(desc.element == ATTR_ELEMENT_FACE) { if(dx) *dx = 0.0f; if(dy) *dy = 0.0f; - return kernel_tex_fetch(__attributes_float, offset + ccl_fetch(sd, prim)); + return kernel_tex_fetch(__attributes_float, desc.offset + ccl_fetch(sd, prim)); } - else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) { + else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) { uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)); - float f0 = kernel_tex_fetch(__attributes_float, offset + tri_vindex.x); - float f1 = kernel_tex_fetch(__attributes_float, offset + tri_vindex.y); - float f2 = kernel_tex_fetch(__attributes_float, offset + tri_vindex.z); + float f0 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.x); + float f1 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.y); + float f2 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.z); #ifdef __RAY_DIFFERENTIALS__ if(dx) *dx = ccl_fetch(sd, du).dx*f0 + ccl_fetch(sd, dv).dx*f1 - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*f2; @@ -127,8 +127,8 @@ ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *s return ccl_fetch(sd, u)*f0 + ccl_fetch(sd, v)*f1 + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*f2; } - else if(elem == ATTR_ELEMENT_CORNER) { - int tri = offset + ccl_fetch(sd, prim)*3; + else if(desc.element == ATTR_ELEMENT_CORNER) { + int tri = desc.offset + ccl_fetch(sd, prim)*3; float f0 = kernel_tex_fetch(__attributes_float, tri + 0); float f1 = kernel_tex_fetch(__attributes_float, tri + 1); float f2 = kernel_tex_fetch(__attributes_float, tri + 2); @@ -148,20 +148,20 @@ ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *s } } -ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy) +ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy) { - if(elem == ATTR_ELEMENT_FACE) { + if(desc.element == ATTR_ELEMENT_FACE) { if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f); if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f); - return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + ccl_fetch(sd, prim))); + return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + ccl_fetch(sd, prim))); } - else if(elem == ATTR_ELEMENT_VERTEX || elem == ATTR_ELEMENT_VERTEX_MOTION) { + else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) { uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, ccl_fetch(sd, prim)); - float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x)); - float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y)); - float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z)); + float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x)); + float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y)); + float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z)); #ifdef __RAY_DIFFERENTIALS__ if(dx) *dx = ccl_fetch(sd, du).dx*f0 + ccl_fetch(sd, dv).dx*f1 - (ccl_fetch(sd, du).dx + ccl_fetch(sd, dv).dx)*f2; @@ -170,11 +170,11 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData return ccl_fetch(sd, u)*f0 + ccl_fetch(sd, v)*f1 + (1.0f - ccl_fetch(sd, u) - ccl_fetch(sd, v))*f2; } - else if(elem == ATTR_ELEMENT_CORNER || elem == ATTR_ELEMENT_CORNER_BYTE) { - int tri = offset + ccl_fetch(sd, prim)*3; + else if(desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) { + int tri = desc.offset + ccl_fetch(sd, prim)*3; float3 f0, f1, f2; - if(elem == ATTR_ELEMENT_CORNER) { + if(desc.element == ATTR_ELEMENT_CORNER) { f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0)); f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1)); f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2)); diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h index 7c8182bc430..efe540a8518 100644 --- a/intern/cycles/kernel/geom/geom_volume.h +++ b/intern/cycles/kernel/geom/geom_volume.h @@ -50,36 +50,35 @@ ccl_device_inline float3 volume_normalized_position(KernelGlobals *kg, { /* todo: optimize this so it's just a single matrix multiplication when * possible (not motion blur), or perhaps even just translation + scale */ - AttributeElement attr_elem; - int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem); + const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM); object_inverse_position_transform(kg, sd, &P); - if(attr_offset != ATTR_STD_NOT_FOUND) { - Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset); + if(desc.offset != ATTR_STD_NOT_FOUND) { + Transform tfm = primitive_attribute_matrix(kg, sd, desc); P = transform_point(&tfm, P); } return P; } -ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int id, float *dx, float *dy) +ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy) { float3 P = volume_normalized_position(kg, sd, sd->P); #ifdef __KERNEL_GPU__ # if __CUDA_ARCH__ >= 300 - CUtexObject tex = kernel_tex_fetch(__bindless_mapping, id); + CUtexObject tex = kernel_tex_fetch(__bindless_mapping, desc.offset); float f = kernel_tex_image_interp_3d_float(tex, P.x, P.y, P.z); float4 r = make_float4(f, f, f, 1.0); # else - float4 r = volume_image_texture_3d(id, P.x, P.y, P.z); + float4 r = volume_image_texture_3d(desc.offset, P.x, P.y, P.z); # endif #else float4 r; if(sd->flag & SD_VOLUME_CUBIC) - r = kernel_tex_image_interp_3d_ex(id, P.x, P.y, P.z, INTERPOLATION_CUBIC); + r = kernel_tex_image_interp_3d_ex(desc.offset, P.x, P.y, P.z, INTERPOLATION_CUBIC); else - r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z); + r = kernel_tex_image_interp_3d(desc.offset, P.x, P.y, P.z); #endif if(dx) *dx = 0.0f; @@ -88,22 +87,22 @@ ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, return average(float4_to_float3(r)); } -ccl_device float3 volume_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int id, float3 *dx, float3 *dy) +ccl_device float3 volume_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy) { float3 P = volume_normalized_position(kg, sd, sd->P); #ifdef __KERNEL_GPU__ # if __CUDA_ARCH__ >= 300 - CUtexObject tex = kernel_tex_fetch(__bindless_mapping, id); + CUtexObject tex = kernel_tex_fetch(__bindless_mapping, desc.offset); float4 r = kernel_tex_image_interp_3d_float4(tex, P.x, P.y, P.z); # else - float4 r = volume_image_texture_3d(id, P.x, P.y, P.z); + float4 r = volume_image_texture_3d(desc.offset, P.x, P.y, P.z); # endif #else float4 r; if(sd->flag & SD_VOLUME_CUBIC) - r = kernel_tex_image_interp_3d_ex(id, P.x, P.y, P.z, INTERPOLATION_CUBIC); + r = kernel_tex_image_interp_3d_ex(desc.offset, P.x, P.y, P.z, INTERPOLATION_CUBIC); else - r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z); + r = kernel_tex_image_interp_3d(desc.offset, P.x, P.y, P.z); #endif if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 18b5c35c768..57b116e1dd7 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -624,6 +624,12 @@ typedef enum AttributeStandard { ATTR_STD_NOT_FOUND = ~0 } AttributeStandard; +typedef struct AttributeDescriptor { + AttributeElement element; + NodeAttributeType type; + int offset; +} AttributeDescriptor; + /* Closure data */ #ifdef __MULTI_CLOSURE__ diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h index 916542ec628..8353c4e434b 100644 --- a/intern/cycles/kernel/osl/osl_globals.h +++ b/intern/cycles/kernel/osl/osl_globals.h @@ -59,8 +59,7 @@ struct OSLGlobals { /* attributes */ struct Attribute { TypeDesc type; - AttributeElement elem; - int offset; + AttributeDescriptor desc; ParamValue value; }; diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index caae24405f1..153ebad6cd2 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -554,13 +554,13 @@ static bool get_mesh_element_attribute(KernelGlobals *kg, const ShaderData *sd, attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) { float3 fval[3]; - fval[0] = primitive_attribute_float3(kg, sd, attr.elem, attr.offset, + fval[0] = primitive_attribute_float3(kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); return set_attribute_float3(fval, type, derivatives, val); } else if(attr.type == TypeDesc::TypeFloat) { float fval[3]; - fval[0] = primitive_attribute_float(kg, sd, attr.elem, attr.offset, + fval[0] = primitive_attribute_float(kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); return set_attribute_float(fval, type, derivatives, val); } @@ -573,7 +573,7 @@ static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OS const TypeDesc& type, bool derivatives, void *val) { if(attr.type == TypeDesc::TypeMatrix) { - Transform tfm = primitive_attribute_matrix(kg, sd, attr.offset); + Transform tfm = primitive_attribute_matrix(kg, sd, attr.desc); return set_attribute_matrix(tfm, type, val); } else { @@ -815,7 +815,7 @@ bool OSLRenderServices::get_attribute(ShaderData *sd, bool derivatives, ustring if(it != attribute_map.end()) { const OSLGlobals::Attribute& attr = it->second; - if(attr.elem != ATTR_ELEMENT_OBJECT) { + if(attr.desc.element != ATTR_ELEMENT_OBJECT) { /* triangle and vertex attributes */ if(get_mesh_element_attribute(kg, sd, attr, type, derivatives, val)) return true; diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index de02ec8f691..20dd167708c 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -334,7 +334,7 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderConte /* Attributes */ -int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem) +int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeDescriptor *desc) { /* for OSL, a hash map is used to lookup the attribute by name. */ int object = sd->object*ATTR_PRIM_TYPES; @@ -348,16 +348,23 @@ int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, if(it != attr_map.end()) { const OSLGlobals::Attribute &osl_attr = it->second; - *elem = osl_attr.elem; + *desc = osl_attr.desc; - if(sd->prim == PRIM_NONE && (AttributeElement)osl_attr.elem != ATTR_ELEMENT_MESH) + if(sd->prim == PRIM_NONE && (AttributeElement)osl_attr.desc.element != ATTR_ELEMENT_MESH) { + desc->offset = ATTR_STD_NOT_FOUND; return ATTR_STD_NOT_FOUND; + } /* return result */ - return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset; + if(osl_attr.desc.element == ATTR_ELEMENT_NONE) { + desc->offset = ATTR_STD_NOT_FOUND; + } + return desc->offset; } - else + else { + desc->offset = ATTR_STD_NOT_FOUND; return (int)ATTR_STD_NOT_FOUND; + } } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h index a185b8b8c05..ad06dd6929d 100644 --- a/intern/cycles/kernel/osl/osl_shader.h +++ b/intern/cycles/kernel/osl/osl_shader.h @@ -59,7 +59,7 @@ public: static void eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx); /* attributes */ - static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem); + static int find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeDescriptor *desc); }; CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h index 0f0858baa11..de978a423b4 100644 --- a/intern/cycles/kernel/svm/svm_attribute.h +++ b/intern/cycles/kernel/svm/svm_attribute.h @@ -18,70 +18,57 @@ CCL_NAMESPACE_BEGIN /* Attribute Node */ -ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, +ccl_device AttributeDescriptor svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeType *type, - NodeAttributeType *mesh_type, AttributeElement *elem, int *offset, uint *out_offset) + uint *out_offset) { *out_offset = node.z; *type = (NodeAttributeType)node.w; + + AttributeDescriptor desc; + if(ccl_fetch(sd, object) != OBJECT_NONE) { - /* find attribute by unique id */ - uint id = node.y; - uint attr_offset = ccl_fetch(sd, object)*kernel_data.bvh.attributes_map_stride; - attr_offset += attribute_primitive_type(kg, sd); - uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); - - while(attr_map.x != id) { - if(UNLIKELY(attr_map.x == ATTR_STD_NONE)) { - *elem = ATTR_ELEMENT_NONE; - *offset = 0; - *mesh_type = (NodeAttributeType)node.w; - return; - } - attr_offset += ATTR_PRIM_TYPES; - attr_map = kernel_tex_fetch(__attributes_map, attr_offset); + desc = find_attribute(kg, sd, node.y); + if(desc.offset == ATTR_STD_NOT_FOUND) { + desc.element = ATTR_ELEMENT_NONE; + desc.offset = 0; + desc.type = (NodeAttributeType)node.w; } - - /* return result */ - *elem = (AttributeElement)attr_map.y; - *offset = as_int(attr_map.z); - *mesh_type = (NodeAttributeType)attr_map.w; } else { /* background */ - *elem = ATTR_ELEMENT_NONE; - *offset = 0; - *mesh_type = (NodeAttributeType)node.w; + desc.element = ATTR_ELEMENT_NONE; + desc.offset = 0; + desc.type = (NodeAttributeType)node.w; } + + return desc; } ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - NodeAttributeType type, mesh_type; - AttributeElement elem; + NodeAttributeType type; uint out_offset; - int offset; - - svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset); + AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); /* fetch and store attribute */ if(type == NODE_ATTR_FLOAT) { - if(mesh_type == NODE_ATTR_FLOAT) { - float f = primitive_attribute_float(kg, sd, elem, offset, NULL, NULL); + if(desc.type == NODE_ATTR_FLOAT) { + float f = primitive_attribute_float(kg, sd, desc, NULL, NULL); stack_store_float(stack, out_offset, f); } else { - float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL); + float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL); stack_store_float(stack, out_offset, average(f)); } } else { - if(mesh_type == NODE_ATTR_FLOAT3) { - float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL); + if(desc.type == NODE_ATTR_FLOAT3) { + float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL); stack_store_float3(stack, out_offset, f); } else { - float f = primitive_attribute_float(kg, sd, elem, offset, NULL, NULL); + float f = primitive_attribute_float(kg, sd, desc, NULL, NULL); stack_store_float3(stack, out_offset, make_float3(f, f, f)); } } @@ -94,35 +81,32 @@ ccl_device_noinline #endif void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - NodeAttributeType type, mesh_type; - AttributeElement elem; + NodeAttributeType type; uint out_offset; - int offset; - - svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset); + AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); /* fetch and store attribute */ if(type == NODE_ATTR_FLOAT) { - if(mesh_type == NODE_ATTR_FLOAT) { + if(desc.type == NODE_ATTR_FLOAT) { float dx; - float f = primitive_attribute_float(kg, sd, elem, offset, &dx, NULL); + float f = primitive_attribute_float(kg, sd, desc, &dx, NULL); stack_store_float(stack, out_offset, f+dx); } else { float3 dx; - float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, NULL); + float3 f = primitive_attribute_float3(kg, sd, desc, &dx, NULL); stack_store_float(stack, out_offset, average(f+dx)); } } else { - if(mesh_type == NODE_ATTR_FLOAT3) { + if(desc.type == NODE_ATTR_FLOAT3) { float3 dx; - float3 f = primitive_attribute_float3(kg, sd, elem, offset, &dx, NULL); + float3 f = primitive_attribute_float3(kg, sd, desc, &dx, NULL); stack_store_float3(stack, out_offset, f+dx); } else { float dx; - float f = primitive_attribute_float(kg, sd, elem, offset, &dx, NULL); + float f = primitive_attribute_float(kg, sd, desc, &dx, NULL); stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx)); } } @@ -138,35 +122,32 @@ void svm_node_attr_bump_dy(KernelGlobals *kg, float *stack, uint4 node) { - NodeAttributeType type, mesh_type; - AttributeElement elem; + NodeAttributeType type; uint out_offset; - int offset; - - svm_node_attr_init(kg, sd, node, &type, &mesh_type, &elem, &offset, &out_offset); + AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); /* fetch and store attribute */ if(type == NODE_ATTR_FLOAT) { - if(mesh_type == NODE_ATTR_FLOAT) { + if(desc.type == NODE_ATTR_FLOAT) { float dy; - float f = primitive_attribute_float(kg, sd, elem, offset, NULL, &dy); + float f = primitive_attribute_float(kg, sd, desc, NULL, &dy); stack_store_float(stack, out_offset, f+dy); } else { float3 dy; - float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, &dy); + float3 f = primitive_attribute_float3(kg, sd, desc, NULL, &dy); stack_store_float(stack, out_offset, average(f+dy)); } } else { - if(mesh_type == NODE_ATTR_FLOAT3) { + if(desc.type == NODE_ATTR_FLOAT3) { float3 dy; - float3 f = primitive_attribute_float3(kg, sd, elem, offset, NULL, &dy); + float3 f = primitive_attribute_float3(kg, sd, desc, NULL, &dy); stack_store_float3(stack, out_offset, f+dy); } else { float dy; - float f = primitive_attribute_float(kg, sd, elem, offset, NULL, &dy); + float f = primitive_attribute_float(kg, sd, desc, NULL, &dy); stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy)); } } diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index b39d6a3e009..01dede3fff5 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -287,23 +287,22 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st } /* first try to get tangent attribute */ - AttributeElement attr_elem, attr_sign_elem, attr_normal_elem; - int attr_offset = find_attribute(kg, sd, node.z, &attr_elem); - int attr_sign_offset = find_attribute(kg, sd, node.w, &attr_sign_elem); - int attr_normal_offset = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL, &attr_normal_elem); + const AttributeDescriptor attr = find_attribute(kg, sd, node.z); + const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w); + const AttributeDescriptor attr_normal = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL); - if(attr_offset == ATTR_STD_NOT_FOUND || attr_sign_offset == ATTR_STD_NOT_FOUND || attr_normal_offset == ATTR_STD_NOT_FOUND) { + if(attr.offset == ATTR_STD_NOT_FOUND || attr_sign.offset == ATTR_STD_NOT_FOUND || attr_normal.offset == ATTR_STD_NOT_FOUND) { stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f)); return; } /* get _unnormalized_ interpolated normal and tangent */ - float3 tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL); - float sign = primitive_attribute_float(kg, sd, attr_sign_elem, attr_sign_offset, NULL, NULL); + float3 tangent = primitive_attribute_float3(kg, sd, attr, NULL, NULL); + float sign = primitive_attribute_float(kg, sd, attr_sign, NULL, NULL); float3 normal; if(ccl_fetch(sd, shader) & SHADER_SMOOTH_NORMAL) { - normal = primitive_attribute_float3(kg, sd, attr_normal_elem, attr_normal_offset, NULL, NULL); + normal = primitive_attribute_float3(kg, sd, attr_normal, NULL, NULL); } else { normal = ccl_fetch(sd, Ng); @@ -356,24 +355,22 @@ ccl_device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack if(direction_type == NODE_TANGENT_UVMAP) { /* UV map */ - AttributeElement attr_elem; - int attr_offset = find_attribute(kg, sd, node.z, &attr_elem); + const AttributeDescriptor desc = find_attribute(kg, sd, node.z); - if(attr_offset == ATTR_STD_NOT_FOUND) + if(desc.offset == ATTR_STD_NOT_FOUND) tangent = make_float3(0.0f, 0.0f, 0.0f); else - tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL); + tangent = primitive_attribute_float3(kg, sd, desc, NULL, NULL); } else { /* radial */ - AttributeElement attr_elem; - int attr_offset = find_attribute(kg, sd, node.z, &attr_elem); + const AttributeDescriptor desc = find_attribute(kg, sd, node.z); float3 generated; - if(attr_offset == ATTR_STD_NOT_FOUND) + if(desc.offset == ATTR_STD_NOT_FOUND) generated = ccl_fetch(sd, P); else - generated = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL); + generated = primitive_attribute_float3(kg, sd, desc, NULL, NULL); if(axis == NODE_TANGENT_AXIS_X) tangent = make_float3(0.0f, -(generated.z - 0.5f), (generated.y - 0.5f)); diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index e8ff81fe08e..a77ae1121a1 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -517,16 +517,19 @@ AttributeRequest::AttributeRequest(ustring name_) std = ATTR_STD_NONE; triangle_type = TypeDesc::TypeFloat; - triangle_element = ATTR_ELEMENT_NONE; - triangle_offset = 0; + triangle_desc.element = ATTR_ELEMENT_NONE; + triangle_desc.offset = 0; + triangle_desc.type = NODE_ATTR_FLOAT; curve_type = TypeDesc::TypeFloat; - curve_element = ATTR_ELEMENT_NONE; - curve_offset = 0; + curve_desc.element = ATTR_ELEMENT_NONE; + curve_desc.offset = 0; + curve_desc.type = NODE_ATTR_FLOAT; subd_type = TypeDesc::TypeFloat; - subd_element = ATTR_ELEMENT_NONE; - subd_offset = 0; + subd_desc.element = ATTR_ELEMENT_NONE; + subd_desc.offset = 0; + subd_desc.type = NODE_ATTR_FLOAT; } AttributeRequest::AttributeRequest(AttributeStandard std_) @@ -535,16 +538,19 @@ AttributeRequest::AttributeRequest(AttributeStandard std_) std = std_; triangle_type = TypeDesc::TypeFloat; - triangle_element = ATTR_ELEMENT_NONE; - triangle_offset = 0; + triangle_desc.element = ATTR_ELEMENT_NONE; + triangle_desc.offset = 0; + triangle_desc.type = NODE_ATTR_FLOAT; curve_type = TypeDesc::TypeFloat; - curve_element = ATTR_ELEMENT_NONE; - curve_offset = 0; + curve_desc.element = ATTR_ELEMENT_NONE; + curve_desc.offset = 0; + curve_desc.type = NODE_ATTR_FLOAT; subd_type = TypeDesc::TypeFloat; - subd_element = ATTR_ELEMENT_NONE; - subd_offset = 0; + subd_desc.element = ATTR_ELEMENT_NONE; + subd_desc.offset = 0; + subd_desc.type = NODE_ATTR_FLOAT; } /* AttributeRequestSet */ diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h index e51bdf28d66..67d067d60c9 100644 --- a/intern/cycles/render/attribute.h +++ b/intern/cycles/render/attribute.h @@ -135,8 +135,7 @@ public: /* temporary variables used by MeshManager */ TypeDesc triangle_type, curve_type, subd_type; - AttributeElement triangle_element, curve_element, subd_element; - int triangle_offset, curve_offset, subd_offset; + AttributeDescriptor triangle_desc, curve_desc, subd_desc; explicit AttributeRequest(ustring name_); explicit AttributeRequest(AttributeStandard std); diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 4cf0a785897..2edec40b131 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -831,9 +831,9 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att OSLGlobals::Attribute osl_attr; osl_attr.type = attr.type(); - osl_attr.elem = ATTR_ELEMENT_OBJECT; + osl_attr.desc.element = ATTR_ELEMENT_OBJECT; osl_attr.value = attr; - osl_attr.offset = 0; + osl_attr.desc.offset = 0; og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_TRIANGLE][attr.name()] = osl_attr; og->attribute_map[i*ATTR_PRIM_TYPES + ATTR_PRIM_CURVE][attr.name()] = osl_attr; @@ -853,9 +853,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att foreach(AttributeRequest& req, attributes.requests) { OSLGlobals::Attribute osl_attr; - if(req.triangle_element != ATTR_ELEMENT_NONE) { - osl_attr.elem = req.triangle_element; - osl_attr.offset = req.triangle_offset; + if(req.triangle_desc.element != ATTR_ELEMENT_NONE) { + osl_attr.desc = req.triangle_desc; if(req.triangle_type == TypeDesc::TypeFloat) osl_attr.type = TypeDesc::TypeFloat; @@ -875,9 +874,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att } } - if(req.curve_element != ATTR_ELEMENT_NONE) { - osl_attr.elem = req.curve_element; - osl_attr.offset = req.curve_offset; + if(req.curve_desc.element != ATTR_ELEMENT_NONE) { + osl_attr.desc = req.curve_desc; if(req.curve_type == TypeDesc::TypeFloat) osl_attr.type = TypeDesc::TypeFloat; @@ -897,9 +895,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att } } - if(req.subd_element != ATTR_ELEMENT_NONE) { - osl_attr.elem = req.subd_element; - osl_attr.offset = req.subd_offset; + if(req.subd_desc.element != ATTR_ELEMENT_NONE) { + osl_attr.desc = req.subd_desc; if(req.subd_type == TypeDesc::TypeFloat) osl_attr.type = TypeDesc::TypeFloat; @@ -971,8 +968,8 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce if(mesh->num_triangles()) { attr_map[index].x = id; - attr_map[index].y = req.triangle_element; - attr_map[index].z = as_uint(req.triangle_offset); + attr_map[index].y = req.triangle_desc.element; + attr_map[index].z = as_uint(req.triangle_desc.offset); if(req.triangle_type == TypeDesc::TypeFloat) attr_map[index].w = NODE_ATTR_FLOAT; @@ -986,8 +983,8 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce if(mesh->num_curves()) { attr_map[index].x = id; - attr_map[index].y = req.curve_element; - attr_map[index].z = as_uint(req.curve_offset); + attr_map[index].y = req.curve_desc.element; + attr_map[index].z = as_uint(req.curve_desc.offset); if(req.curve_type == TypeDesc::TypeFloat) attr_map[index].w = NODE_ATTR_FLOAT; @@ -1001,8 +998,8 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce if(mesh->subd_faces.size()) { attr_map[index].x = id; - attr_map[index].y = req.subd_element; - attr_map[index].z = as_uint(req.subd_offset); + attr_map[index].y = req.subd_desc.element; + attr_map[index].z = as_uint(req.subd_desc.offset); if(req.subd_type == TypeDesc::TypeFloat) attr_map[index].w = NODE_ATTR_FLOAT; @@ -1069,17 +1066,19 @@ static void update_attribute_element_offset(Mesh *mesh, Attribute *mattr, AttributePrimitive prim, TypeDesc& type, - int& offset, - AttributeElement& element) + AttributeDescriptor& desc) { if(mattr) { /* store element and type */ - element = mattr->element; + desc.element = mattr->element; type = mattr->type; /* store attribute data in arrays */ size_t size = mattr->element_size(mesh, prim); + AttributeElement& element = desc.element; + int& offset = desc.offset; + if(mattr->element == ATTR_ELEMENT_VOXEL) { /* store slot in offset value */ VoxelAttribute *voxel_data = mattr->data_voxel(); @@ -1153,8 +1152,8 @@ static void update_attribute_element_offset(Mesh *mesh, } else { /* attribute not found */ - element = ATTR_ELEMENT_NONE; - offset = 0; + desc.element = ATTR_ELEMENT_NONE; + desc.offset = 0; } } @@ -1243,8 +1242,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, triangle_mattr, ATTR_PRIM_TRIANGLE, req.triangle_type, - req.triangle_offset, - req.triangle_element); + req.triangle_desc); update_attribute_element_offset(mesh, attr_float, attr_float_offset, @@ -1253,8 +1251,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, curve_mattr, ATTR_PRIM_CURVE, req.curve_type, - req.curve_offset, - req.curve_element); + req.curve_desc); update_attribute_element_offset(mesh, attr_float, attr_float_offset, @@ -1263,8 +1260,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene, subd_mattr, ATTR_PRIM_SUBD, req.subd_type, - req.subd_offset, - req.subd_element); + req.subd_desc); if(progress.get_cancel()) return; } |