Fix for attribute lookup in OSL. This uses a map in the OSL globals instead of the...
authorLukas Toenne <lukas.toenne@googlemail.com>
Wed, 5 Sep 2012 17:08:56 +0000 (17:08 +0000)
committerLukas Toenne <lukas.toenne@googlemail.com>
Wed, 5 Sep 2012 17:08:56 +0000 (17:08 +0000)
intern/cycles/kernel/kernel_triangle.h
intern/cycles/kernel/kernel_types.h
intern/cycles/render/attribute.cpp
intern/cycles/render/attribute.h
intern/cycles/render/mesh.cpp

index 492800e8aabaaab2ad58775997d0cdbe34aa2194..60d6d9356ec2f1f8d11637b01c159676bf0d6dbe 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
+
 #include "kernel_projection.h"
 
+#include "util_param.h"
+
 CCL_NAMESPACE_BEGIN
 
 /* Point on triangle for Moller-Trumbore triangles */
@@ -183,17 +185,39 @@ __device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *s
 
 /* motion */
 
+/* note: declared in kernel.h, have to add it here because kernel.h is not available */
+bool kernel_osl_use(KernelGlobals *kg);
+
 __device int triangle_find_attribute(KernelGlobals *kg, ShaderData *sd, uint id)
 {
-       /* find attribute by unique id */
-       uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
-       uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
-       while(attr_map.x != id)
-               attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
 
-       /* return result */
-       return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : attr_map.z;
+#ifdef __OSL__
+       if (kernel_osl_use(kg)) {
+               /* for OSL, a hash map is used to lookup the attribute by name. */
+               OSLGlobals::AttributeMap &attr_map = kg->osl.attribute_map[sd->object];
+               ustring stdname = ustring(std::string("std::") + attribute_standard_name((AttributeStandard)id).c_str());
+               OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
+               if (it != attr_map.end()) {
+                       const OSLGlobals::Attribute &osl_attr = it->second;
+                       /* return result */
+                       return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset;
+               }
+               else
+                       return (int)ATTR_STD_NOT_FOUND;
+       }
+       else
+#endif
+       {
+               /* for SVM, find attribute by unique id */
+               uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+               uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+               
+               while(attr_map.x != id)
+                       attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
+               
+               /* return result */
+               return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : attr_map.z;
+       }
 }
 
 __device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd)
index 39e088583c47e9d0fdb5dd3ee574a7b68ae94c10..738d459df30eb1845a3f0e0bc48eadd15a320154 100644 (file)
@@ -22,6 +22,8 @@
 #include "kernel_math.h"
 #include "svm/svm_types.h"
 
+#include "util_param.h"
+
 #ifndef __KERNEL_GPU__
 #define __KERNEL_CPU__
 #endif
@@ -368,6 +370,30 @@ typedef enum AttributeStandard {
        ATTR_STD_NOT_FOUND = ~0
 } AttributeStandard;
 
+__device ustring attribute_standard_name(AttributeStandard std)
+{
+       if(std == ATTR_STD_VERTEX_NORMAL)
+               return ustring("N");
+       else if(std == ATTR_STD_FACE_NORMAL)
+               return ustring("Ng");
+       else if(std == ATTR_STD_UV)
+               return ustring("uv");
+       else if(std == ATTR_STD_GENERATED)
+               return ustring("generated");
+       else if(std == ATTR_STD_POSITION_UNDEFORMED)
+               return ustring("undeformed");
+       else if(std == ATTR_STD_POSITION_UNDISPLACED)
+               return ustring("undisplaced");
+       else if(std == ATTR_STD_MOTION_PRE)
+               return ustring("motion_pre");
+       else if(std == ATTR_STD_MOTION_POST)
+               return ustring("motion_post");
+       else if(std == ATTR_STD_PARTICLE)
+               return ustring("particle");
+       
+       return ustring();
+}
+
 /* Closure data */
 
 #define MAX_CLOSURE 8
index 7296f8bebba4d4b04d636d871c2d277c786d58a4..5122c1af4101ff3baf68f446539cd3ff601f9c96 100644 (file)
@@ -84,30 +84,6 @@ bool Attribute::same_storage(TypeDesc a, TypeDesc b)
        return false;
 }
 
-ustring Attribute::standard_name(AttributeStandard std)
-{
-       if(std == ATTR_STD_VERTEX_NORMAL)
-               return ustring("N");
-       else if(std == ATTR_STD_FACE_NORMAL)
-               return ustring("Ng");
-       else if(std == ATTR_STD_UV)
-               return ustring("uv");
-       else if(std == ATTR_STD_GENERATED)
-               return ustring("generated");
-       else if(std == ATTR_STD_POSITION_UNDEFORMED)
-               return ustring("undeformed");
-       else if(std == ATTR_STD_POSITION_UNDISPLACED)
-               return ustring("undisplaced");
-       else if(std == ATTR_STD_MOTION_PRE)
-               return ustring("motion_pre");
-       else if(std == ATTR_STD_MOTION_POST)
-               return ustring("motion_post");
-       else if(std == ATTR_STD_PARTICLE)
-               return ustring("particle");
-
-       return ustring();
-}
-
 /* Attribute Set */
 
 AttributeSet::AttributeSet()
@@ -178,7 +154,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
        Attribute *attr = NULL;
 
        if(name == ustring())
-               name = Attribute::standard_name(std);
+               name = attribute_standard_name(std);
 
        if(std == ATTR_STD_VERTEX_NORMAL)
                attr = add(name, TypeDesc::TypeNormal, Attribute::VERTEX);
index 707d558fc794465c937ac0acc3613a1d9de34ceb..e95bf42f6ae942ef05035c3d20775d395b4b6db9 100644 (file)
@@ -71,7 +71,6 @@ public:
        const float *data_float() const { return (float*)data(); }
 
        static bool same_storage(TypeDesc a, TypeDesc b);
-       static ustring standard_name(AttributeStandard std);
 };
 
 /* Attribute Set
index 8f5f2647ebf2941f91d87b91cad376de73e58e17..1d9683f25ccedbf5ae2ce9c681225d6d78a49ad7 100644 (file)
@@ -366,7 +366,7 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
 
                        if(req.std != ATTR_STD_NONE) {
                                /* if standard attribute, add lookup by std:: name convention */
-                               ustring stdname = ustring(string("std::") + Attribute::standard_name(req.std).c_str());
+                               ustring stdname = ustring(string("std::") + attribute_standard_name(req.std).c_str());
                                og->attribute_map[i][stdname] = osl_attr;
                        }
                        else if(req.name != ustring()) {