Code refactor: use KernelOject struct instead of float4 array.
authorStefan Werner <stefan.werner@tangent-animation.com>
Wed, 7 Mar 2018 21:19:56 +0000 (22:19 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sat, 10 Mar 2018 03:54:04 +0000 (04:54 +0100)
Original patch by Stefan with modifications by Brecht.

intern/cycles/kernel/geom/geom_attribute.h
intern/cycles/kernel/geom/geom_object.h
intern/cycles/kernel/kernel_textures.h
intern/cycles/kernel/kernel_types.h
intern/cycles/render/object.cpp
intern/cycles/render/object.h
intern/cycles/render/scene.h

index c72595e..6e2ee3b 100644 (file)
@@ -53,9 +53,7 @@ ccl_device_inline AttributeDescriptor attribute_not_found()
 
 ccl_device_inline uint object_attribute_map_offset(KernelGlobals *kg, int object)
 {
-       int offset = object*OBJECT_SIZE + 15;
-       float4 f = kernel_tex_fetch(__objects, offset);
-       return __float_as_uint(f.y);
+       return kernel_tex_fetch(__objects, object).attribute_map_offset;
 }
 
 ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)
index 32aa200..6bb4d13 100644 (file)
@@ -29,11 +29,6 @@ CCL_NAMESPACE_BEGIN
 enum ObjectTransform {
        OBJECT_TRANSFORM = 0,
        OBJECT_INVERSE_TRANSFORM = 4,
-       OBJECT_TRANSFORM_MOTION_PRE = 0,
-       OBJECT_TRANSFORM_MOTION_MID = 4,
-       OBJECT_TRANSFORM_MOTION_POST = 8,
-       OBJECT_PROPERTIES = 12,
-       OBJECT_DUPLI = 13
 };
 
 enum ObjectVectorTransform {
@@ -45,12 +40,17 @@ enum ObjectVectorTransform {
 
 ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
 {
-       int offset = object*OBJECT_SIZE + (int)type;
-
        Transform tfm;
-       tfm.x = kernel_tex_fetch(__objects, offset + 0);
-       tfm.y = kernel_tex_fetch(__objects, offset + 1);
-       tfm.z = kernel_tex_fetch(__objects, offset + 2);
+       if(type == OBJECT_INVERSE_TRANSFORM) {
+               tfm.x = kernel_tex_fetch(__objects, object).tfm.mid.x;
+               tfm.y = kernel_tex_fetch(__objects, object).tfm.mid.y;
+               tfm.z = kernel_tex_fetch(__objects, object).tfm.mid.z;
+       }
+       else {
+               tfm.x = kernel_tex_fetch(__objects, object).tfm.pre.x;
+               tfm.y = kernel_tex_fetch(__objects, object).tfm.pre.y;
+               tfm.z = kernel_tex_fetch(__objects, object).tfm.pre.z;
+       }
        tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
 
        return tfm;
@@ -91,24 +91,7 @@ ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int
 #ifdef __OBJECT_MOTION__
 ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
 {
-       MotionTransform motion;
-
-       int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE;
-
-       motion.pre.x = kernel_tex_fetch(__objects, offset + 0);
-       motion.pre.y = kernel_tex_fetch(__objects, offset + 1);
-       motion.pre.z = kernel_tex_fetch(__objects, offset + 2);
-       motion.pre.w = kernel_tex_fetch(__objects, offset + 3);
-
-       motion.mid.x = kernel_tex_fetch(__objects, offset + 4);
-       motion.mid.y = kernel_tex_fetch(__objects, offset + 5);
-       motion.mid.z = kernel_tex_fetch(__objects, offset + 6);
-       motion.mid.w = kernel_tex_fetch(__objects, offset + 7);
-
-       motion.post.x = kernel_tex_fetch(__objects, offset + 8);
-       motion.post.y = kernel_tex_fetch(__objects, offset + 9);
-       motion.post.z = kernel_tex_fetch(__objects, offset + 10);
-       motion.post.w = kernel_tex_fetch(__objects, offset + 11);
+       MotionTransform motion = kernel_tex_fetch(__objects, object).tfm;
 
        Transform tfm;
        transform_motion_interpolate(&tfm, &motion, time);
@@ -237,9 +220,7 @@ ccl_device_inline float3 object_location(KernelGlobals *kg, const ShaderData *sd
 
 ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
 {
-       int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
-       float4 f = kernel_tex_fetch(__objects, offset);
-       return f.x;
+       return kernel_tex_fetch(__objects, object).surface_area;
 }
 
 /* Pass ID number of object */
@@ -249,9 +230,7 @@ ccl_device_inline float object_pass_id(KernelGlobals *kg, int object)
        if(object == OBJECT_NONE)
                return 0.0f;
 
-       int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
-       float4 f = kernel_tex_fetch(__objects, offset);
-       return f.y;
+       return kernel_tex_fetch(__objects, object).pass_id;
 }
 
 /* Per lamp random number for shader variation */
@@ -272,9 +251,7 @@ ccl_device_inline float object_random_number(KernelGlobals *kg, int object)
        if(object == OBJECT_NONE)
                return 0.0f;
 
-       int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
-       float4 f = kernel_tex_fetch(__objects, offset);
-       return f.z;
+       return kernel_tex_fetch(__objects, object).random_number;
 }
 
 /* Particle ID from which this object was generated */
@@ -284,9 +261,7 @@ ccl_device_inline int object_particle_id(KernelGlobals *kg, int object)
        if(object == OBJECT_NONE)
                return 0;
 
-       int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
-       float4 f = kernel_tex_fetch(__objects, offset);
-       return __float_as_uint(f.w);
+       return kernel_tex_fetch(__objects, object).particle_index;
 }
 
 /* Generated texture coordinate on surface from where object was instanced */
@@ -296,9 +271,10 @@ ccl_device_inline float3 object_dupli_generated(KernelGlobals *kg, int object)
        if(object == OBJECT_NONE)
                return make_float3(0.0f, 0.0f, 0.0f);
 
-       int offset = object*OBJECT_SIZE + OBJECT_DUPLI;
-       float4 f = kernel_tex_fetch(__objects, offset);
-       return make_float3(f.x, f.y, f.z);
+       const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object);
+       return make_float3(kobject->dupli_generated[0],
+                          kobject->dupli_generated[1],
+                          kobject->dupli_generated[2]);
 }
 
 /* UV texture coordinate on surface from where object was instanced */
@@ -308,27 +284,24 @@ ccl_device_inline float3 object_dupli_uv(KernelGlobals *kg, int object)
        if(object == OBJECT_NONE)
                return make_float3(0.0f, 0.0f, 0.0f);
 
-       int offset = object*OBJECT_SIZE + OBJECT_DUPLI;
-       float4 f = kernel_tex_fetch(__objects, offset + 1);
-       return make_float3(f.x, f.y, 0.0f);
+       const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object);
+       return make_float3(kobject->dupli_uv[0],
+                          kobject->dupli_uv[1],
+                          0.0f);
 }
 
 /* Information about mesh for motion blurred triangles and curves */
 
 ccl_device_inline void object_motion_info(KernelGlobals *kg, int object, int *numsteps, int *numverts, int *numkeys)
 {
-       int offset = object*OBJECT_SIZE + OBJECT_DUPLI;
-
        if(numkeys) {
-               float4 f = kernel_tex_fetch(__objects, offset);
-               *numkeys = __float_as_int(f.w);
+               *numkeys = kernel_tex_fetch(__objects, object).numkeys;
        }
 
-       float4 f = kernel_tex_fetch(__objects, offset + 1);
        if(numsteps)
-               *numsteps = __float_as_int(f.z);
+               *numsteps = kernel_tex_fetch(__objects, object).numsteps;
        if(numverts)
-               *numverts = __float_as_int(f.w);
+               *numverts = kernel_tex_fetch(__objects, object).numverts;
 }
 
 /* Offset to an objects patch map */
@@ -338,9 +311,7 @@ ccl_device_inline uint object_patch_map_offset(KernelGlobals *kg, int object)
        if(object == OBJECT_NONE)
                return 0;
 
-       int offset = object*OBJECT_SIZE + 15;
-       float4 f = kernel_tex_fetch(__objects, offset);
-       return __float_as_uint(f.x);
+       return kernel_tex_fetch(__objects, object).patch_map_offset;
 }
 
 /* Pass ID for shader */
index 74b6595..427ed14 100644 (file)
@@ -31,7 +31,7 @@ KERNEL_TEX(uint, __object_node)
 KERNEL_TEX(float2, __prim_time)
 
 /* objects */
-KERNEL_TEX(float4, __objects)
+KERNEL_TEX(KernelObject, __objects)
 KERNEL_TEX(float4, __objects_vector)
 
 /* triangles */
index 2a437cd..b6f1a3a 100644 (file)
@@ -35,7 +35,6 @@
 CCL_NAMESPACE_BEGIN
 
 /* Constants */
-#define OBJECT_SIZE            16
 #define OBJECT_VECTOR_SIZE     6
 #define LIGHT_SIZE             11
 #define FILTER_TABLE_SIZE      1024
@@ -1434,6 +1433,30 @@ typedef struct KernelData {
 } KernelData;
 static_assert_align(KernelData, 16);
 
+/* Kernel data structures. */
+
+typedef struct KernelObject {
+       MotionTransform tfm;
+
+       float surface_area;
+       float pass_id;
+       float random_number;
+       int particle_index;
+
+       float dupli_generated[3];
+       float dupli_uv[2];
+
+       int numkeys;
+       int numsteps;
+       int numverts;
+
+       uint patch_map_offset;
+       uint attribute_map_offset;
+       uint pad1, pad2;
+} KernelObject;;
+static_assert_align(KernelObject, 16);
+
+
 /* Declarations required for split kernel */
 
 /* Macro for queues */
index b981d2b..c992469 100644 (file)
@@ -289,7 +289,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
                                                    Object *ob,
                                                    int object_index)
 {
-       float4 *objects = state->objects;
+       KernelObject& kobject = state->objects[object_index];
        float4 *objects_vector = state->objects_vector;
 
        Mesh *mesh = ob->mesh;
@@ -357,15 +357,15 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
                }
        }
 
-       /* Pack in texture. */
-       int offset = object_index*OBJECT_SIZE;
-
        /* OBJECT_TRANSFORM */
-       memcpy(&objects[offset], &tfm, sizeof(float4)*3);
+       memcpy(&kobject.tfm.pre, &tfm, sizeof(float4)*3);
        /* OBJECT_INVERSE_TRANSFORM */
-       memcpy(&objects[offset+4], &itfm, sizeof(float4)*3);
+       memcpy(&kobject.tfm.mid, &itfm, sizeof(float4)*3);
        /* OBJECT_PROPERTIES */
-       objects[offset+12] = make_float4(surface_area, pass_id, random_number, __int_as_float(particle_index));
+       kobject.surface_area = surface_area;
+       kobject.pass_id = pass_id;
+       kobject.random_number = random_number;
+       kobject.particle_index = particle_index;
 
        if(mesh->use_motion_blur) {
                state->have_motion = true;
@@ -404,21 +404,24 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
                        MotionTransform decomp;
 
                        transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
-                       memcpy(&objects[offset], &decomp, sizeof(float4)*12);
+                       kobject.tfm = decomp;
                        flag |= SD_OBJECT_MOTION;
                        state->have_motion = true;
                }
        }
 
        /* Dupli object coords and motion info. */
+       kobject.dupli_generated[0] = ob->dupli_generated[0];
+       kobject.dupli_generated[1] = ob->dupli_generated[1];
+       kobject.dupli_generated[2] = ob->dupli_generated[2];
+       kobject.numkeys = mesh->curve_keys.size();
+       kobject.dupli_uv[0] = ob->dupli_uv[0];
+       kobject.dupli_uv[1] = ob->dupli_uv[1];
        int totalsteps = mesh->motion_steps;
-       int numsteps = (totalsteps - 1)/2;
-       int numverts = mesh->verts.size();
-       int numkeys = mesh->curve_keys.size();
-
-       objects[offset+13] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], __int_as_float(numkeys));
-       objects[offset+14] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], __int_as_float(numsteps), __int_as_float(numverts));
-       objects[offset+15] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+       kobject.numsteps = (totalsteps - 1)/2;
+       kobject.numverts = mesh->verts.size();;
+       kobject.patch_map_offset = 0;
+       kobject.attribute_map_offset = 0;
 
        /* Object flag. */
        if(ob->use_holdout) {
@@ -486,7 +489,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene,
        state.queue_start_object = 0;
 
        state.object_flag = object_flag;
-       state.objects = dscene->objects.alloc(OBJECT_SIZE*scene->objects.size());
+       state.objects = dscene->objects.alloc(scene->objects.size());
        if(state.need_motion == Scene::MOTION_PASS) {
                state.objects_vector = dscene->objects_vector.alloc(OBJECT_VECTOR_SIZE*scene->objects.size());
        }
@@ -652,27 +655,26 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc
                return;
        }
 
-       uint4* objects = (uint4*)dscene->objects.data();
+       KernelObject *kobjects = dscene->objects.data();
 
        bool update = false;
        int object_index = 0;
 
        foreach(Object *object, scene->objects) {
                Mesh* mesh = object->mesh;
-               int offset = object_index*OBJECT_SIZE + 15;
 
                if(mesh->patch_table) {
                        uint patch_map_offset = 2*(mesh->patch_table_offset + mesh->patch_table->total_size() -
                                                   mesh->patch_table->num_nodes * PATCH_NODE_SIZE) - mesh->patch_offset;
 
-                       if(objects[offset].x != patch_map_offset) {
-                               objects[offset].x = patch_map_offset;
+                       if(kobjects[object_index].patch_map_offset != patch_map_offset) {
+                               kobjects[object_index].patch_map_offset = patch_map_offset;
                                update = true;
                        }
                }
 
-               if(objects[offset].y != mesh->attr_map_offset) {
-                       objects[offset].y = mesh->attr_map_offset;
+               if(kobjects[object_index].attribute_map_offset != mesh->attr_map_offset) {
+                       kobjects[object_index].attribute_map_offset = mesh->attr_map_offset;
                        update = true;
                }
 
index acdb1b6..54046d7 100644 (file)
@@ -134,7 +134,7 @@ protected:
 
                /* Packed object arrays. Those will be filled in. */
                uint *object_flag;
-               float4 *objects;
+               KernelObject *objects;
                float4 *objects_vector;
 
                /* Flags which will be synchronized to Integrator. */
index ea9485f..48e9ae4 100644 (file)
@@ -86,7 +86,7 @@ public:
        device_vector<uint> patches;
 
        /* objects */
-       device_vector<float4> objects;
+       device_vector<KernelObject> objects;
        device_vector<float4> objects_vector;
 
        /* attributes */