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
This commit is contained in:
Mai Lavelle
2016-07-01 17:36:27 -04:00
parent 734e0aca38
commit cd809b95d8
16 changed files with 249 additions and 254 deletions

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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));

View File

@@ -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);

View File

@@ -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__

View File

@@ -59,8 +59,7 @@ struct OSLGlobals {
/* attributes */
struct Attribute {
TypeDesc type;
AttributeElement elem;
int offset;
AttributeDescriptor desc;
ParamValue value;
};

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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));

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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;
}