Cycles: Remove ccl_fetch and SOA
[blender.git] / intern / cycles / kernel / geom / geom_attribute.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 CCL_NAMESPACE_BEGIN
18
19 /* Attributes
20  *
21  * We support an arbitrary number of attributes on various mesh elements.
22  * On vertices, triangles, curve keys, curves, meshes and volume grids.
23  * Most of the code for attribute reading is in the primitive files.
24  *
25  * Lookup of attributes is different between OSL and SVM, as OSL is ustring
26  * based while for SVM we use integer ids. */
27
28 ccl_device_inline uint subd_triangle_patch(KernelGlobals *kg, const ShaderData *sd);
29
30 ccl_device_inline uint attribute_primitive_type(KernelGlobals *kg, const ShaderData *sd)
31 {
32 #ifdef __HAIR__
33         if(sd->type & PRIMITIVE_ALL_CURVE) {
34                 return ATTR_PRIM_CURVE;
35         }
36         else
37 #endif
38         if(subd_triangle_patch(kg, sd) != ~0) {
39                 return ATTR_PRIM_SUBD;
40         }
41         else {
42                 return ATTR_PRIM_TRIANGLE;
43         }
44 }
45
46 ccl_device_inline AttributeDescriptor attribute_not_found()
47 {
48         const AttributeDescriptor desc = {ATTR_ELEMENT_NONE, (NodeAttributeType)0, 0, ATTR_STD_NOT_FOUND};
49         return desc;
50 }
51
52 /* Find attribute based on ID */
53
54 ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)
55 {
56         if(sd->object == PRIM_NONE) {
57                 return attribute_not_found();
58         }
59
60         /* for SVM, find attribute by unique id */
61         uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
62         attr_offset += attribute_primitive_type(kg, sd);
63         uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
64         
65         while(attr_map.x != id) {
66                 if(UNLIKELY(attr_map.x == ATTR_STD_NONE)) {
67                         return attribute_not_found();
68                 }
69                 attr_offset += ATTR_PRIM_TYPES;
70                 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
71         }
72
73         AttributeDescriptor desc;
74         desc.element = (AttributeElement)attr_map.y;
75         
76         if(sd->prim == PRIM_NONE &&
77            desc.element != ATTR_ELEMENT_MESH &&
78            desc.element != ATTR_ELEMENT_VOXEL &&
79            desc.element != ATTR_ELEMENT_OBJECT)
80         {
81                 return attribute_not_found();
82         }
83
84         /* return result */
85         desc.offset = (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
86         desc.type = (NodeAttributeType)(attr_map.w & 0xff);
87         desc.flags = (AttributeFlag)(attr_map.w >> 8);
88
89         return desc;
90 }
91
92 /* Transform matrix attribute on meshes */
93
94 ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc)
95 {
96         Transform tfm;
97
98         tfm.x = kernel_tex_fetch(__attributes_float3, desc.offset + 0);
99         tfm.y = kernel_tex_fetch(__attributes_float3, desc.offset + 1);
100         tfm.z = kernel_tex_fetch(__attributes_float3, desc.offset + 2);
101         tfm.w = kernel_tex_fetch(__attributes_float3, desc.offset + 3);
102
103         return tfm;
104 }
105
106 CCL_NAMESPACE_END
107