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
path: root/intern
diff options
context:
space:
mode:
authorMai Lavelle <mai.lavelle@gmail.com>2016-07-02 00:36:27 +0300
committerMai Lavelle <mai.lavelle@gmail.com>2016-08-06 06:49:21 +0300
commitcd809b95d828677468298f1eba54fc52bbb9db60 (patch)
treeeb6830d04eb2388f8fa0c7a34f65ee5448e0ec87 /intern
parent734e0aca3872410dcaaf351e091a49a8d6186de2 (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.h38
-rw-r--r--intern/cycles/kernel/geom/geom_curve.h24
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h65
-rw-r--r--intern/cycles/kernel/geom/geom_subd_triangle.h62
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h38
-rw-r--r--intern/cycles/kernel/geom/geom_volume.h27
-rw-r--r--intern/cycles/kernel/kernel_types.h6
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h3
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp8
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp17
-rw-r--r--intern/cycles/kernel/osl/osl_shader.h2
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h97
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h29
-rw-r--r--intern/cycles/render/attribute.cpp30
-rw-r--r--intern/cycles/render/attribute.h3
-rw-r--r--intern/cycles/render/mesh.cpp52
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;
}