Code refactor: use KernelOject struct instead of float4 array.

Original patch by Stefan with modifications by Brecht.
This commit is contained in:
Stefan Werner 2018-03-07 22:19:56 +01:00 committed by Brecht Van Lommel
parent 41b38c5f75
commit f66ff4ee86
7 changed files with 79 additions and 85 deletions

@ -53,9 +53,7 @@ ccl_device_inline AttributeDescriptor attribute_not_found()
ccl_device_inline uint object_attribute_map_offset(KernelGlobals *kg, int object) ccl_device_inline uint object_attribute_map_offset(KernelGlobals *kg, int object)
{ {
int offset = object*OBJECT_SIZE + 15; return kernel_tex_fetch(__objects, object).attribute_map_offset;
float4 f = kernel_tex_fetch(__objects, offset);
return __float_as_uint(f.y);
} }
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id) ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id)

@ -29,11 +29,6 @@ CCL_NAMESPACE_BEGIN
enum ObjectTransform { enum ObjectTransform {
OBJECT_TRANSFORM = 0, OBJECT_TRANSFORM = 0,
OBJECT_INVERSE_TRANSFORM = 4, 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 { enum ObjectVectorTransform {
@ -45,12 +40,17 @@ enum ObjectVectorTransform {
ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
{ {
int offset = object*OBJECT_SIZE + (int)type;
Transform tfm; Transform tfm;
tfm.x = kernel_tex_fetch(__objects, offset + 0); if(type == OBJECT_INVERSE_TRANSFORM) {
tfm.y = kernel_tex_fetch(__objects, offset + 1); tfm.x = kernel_tex_fetch(__objects, object).tfm.mid.x;
tfm.z = kernel_tex_fetch(__objects, offset + 2); 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); tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
return tfm; return tfm;
@ -91,24 +91,7 @@ ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int
#ifdef __OBJECT_MOTION__ #ifdef __OBJECT_MOTION__
ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time) ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
{ {
MotionTransform motion; MotionTransform motion = kernel_tex_fetch(__objects, object).tfm;
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);
Transform tfm; Transform tfm;
transform_motion_interpolate(&tfm, &motion, time); 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) ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
{ {
int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; return kernel_tex_fetch(__objects, object).surface_area;
float4 f = kernel_tex_fetch(__objects, offset);
return f.x;
} }
/* Pass ID number of object */ /* Pass ID number of object */
@ -249,9 +230,7 @@ ccl_device_inline float object_pass_id(KernelGlobals *kg, int object)
if(object == OBJECT_NONE) if(object == OBJECT_NONE)
return 0.0f; return 0.0f;
int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; return kernel_tex_fetch(__objects, object).pass_id;
float4 f = kernel_tex_fetch(__objects, offset);
return f.y;
} }
/* Per lamp random number for shader variation */ /* 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) if(object == OBJECT_NONE)
return 0.0f; return 0.0f;
int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; return kernel_tex_fetch(__objects, object).random_number;
float4 f = kernel_tex_fetch(__objects, offset);
return f.z;
} }
/* Particle ID from which this object was generated */ /* 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) if(object == OBJECT_NONE)
return 0; return 0;
int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; return kernel_tex_fetch(__objects, object).particle_index;
float4 f = kernel_tex_fetch(__objects, offset);
return __float_as_uint(f.w);
} }
/* Generated texture coordinate on surface from where object was instanced */ /* 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) if(object == OBJECT_NONE)
return make_float3(0.0f, 0.0f, 0.0f); return make_float3(0.0f, 0.0f, 0.0f);
int offset = object*OBJECT_SIZE + OBJECT_DUPLI; const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object);
float4 f = kernel_tex_fetch(__objects, offset); return make_float3(kobject->dupli_generated[0],
return make_float3(f.x, f.y, f.z); kobject->dupli_generated[1],
kobject->dupli_generated[2]);
} }
/* UV texture coordinate on surface from where object was instanced */ /* 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) if(object == OBJECT_NONE)
return make_float3(0.0f, 0.0f, 0.0f); return make_float3(0.0f, 0.0f, 0.0f);
int offset = object*OBJECT_SIZE + OBJECT_DUPLI; const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object);
float4 f = kernel_tex_fetch(__objects, offset + 1); return make_float3(kobject->dupli_uv[0],
return make_float3(f.x, f.y, 0.0f); kobject->dupli_uv[1],
0.0f);
} }
/* Information about mesh for motion blurred triangles and curves */ /* 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) 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) { if(numkeys) {
float4 f = kernel_tex_fetch(__objects, offset); *numkeys = kernel_tex_fetch(__objects, object).numkeys;
*numkeys = __float_as_int(f.w);
} }
float4 f = kernel_tex_fetch(__objects, offset + 1);
if(numsteps) if(numsteps)
*numsteps = __float_as_int(f.z); *numsteps = kernel_tex_fetch(__objects, object).numsteps;
if(numverts) if(numverts)
*numverts = __float_as_int(f.w); *numverts = kernel_tex_fetch(__objects, object).numverts;
} }
/* Offset to an objects patch map */ /* 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) if(object == OBJECT_NONE)
return 0; return 0;
int offset = object*OBJECT_SIZE + 15; return kernel_tex_fetch(__objects, object).patch_map_offset;
float4 f = kernel_tex_fetch(__objects, offset);
return __float_as_uint(f.x);
} }
/* Pass ID for shader */ /* Pass ID for shader */

@ -31,7 +31,7 @@ KERNEL_TEX(uint, __object_node)
KERNEL_TEX(float2, __prim_time) KERNEL_TEX(float2, __prim_time)
/* objects */ /* objects */
KERNEL_TEX(float4, __objects) KERNEL_TEX(KernelObject, __objects)
KERNEL_TEX(float4, __objects_vector) KERNEL_TEX(float4, __objects_vector)
/* triangles */ /* triangles */

@ -35,7 +35,6 @@
CCL_NAMESPACE_BEGIN CCL_NAMESPACE_BEGIN
/* Constants */ /* Constants */
#define OBJECT_SIZE 16
#define OBJECT_VECTOR_SIZE 6 #define OBJECT_VECTOR_SIZE 6
#define LIGHT_SIZE 11 #define LIGHT_SIZE 11
#define FILTER_TABLE_SIZE 1024 #define FILTER_TABLE_SIZE 1024
@ -1434,6 +1433,30 @@ typedef struct KernelData {
} KernelData; } KernelData;
static_assert_align(KernelData, 16); 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 */ /* Declarations required for split kernel */
/* Macro for queues */ /* Macro for queues */

@ -289,7 +289,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
Object *ob, Object *ob,
int object_index) int object_index)
{ {
float4 *objects = state->objects; KernelObject& kobject = state->objects[object_index];
float4 *objects_vector = state->objects_vector; float4 *objects_vector = state->objects_vector;
Mesh *mesh = ob->mesh; 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 */ /* OBJECT_TRANSFORM */
memcpy(&objects[offset], &tfm, sizeof(float4)*3); memcpy(&kobject.tfm.pre, &tfm, sizeof(float4)*3);
/* OBJECT_INVERSE_TRANSFORM */ /* OBJECT_INVERSE_TRANSFORM */
memcpy(&objects[offset+4], &itfm, sizeof(float4)*3); memcpy(&kobject.tfm.mid, &itfm, sizeof(float4)*3);
/* OBJECT_PROPERTIES */ /* 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) { if(mesh->use_motion_blur) {
state->have_motion = true; state->have_motion = true;
@ -404,21 +404,24 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
MotionTransform decomp; MotionTransform decomp;
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm); transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
memcpy(&objects[offset], &decomp, sizeof(float4)*12); kobject.tfm = decomp;
flag |= SD_OBJECT_MOTION; flag |= SD_OBJECT_MOTION;
state->have_motion = true; state->have_motion = true;
} }
} }
/* Dupli object coords and motion info. */ /* 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 totalsteps = mesh->motion_steps;
int numsteps = (totalsteps - 1)/2; kobject.numsteps = (totalsteps - 1)/2;
int numverts = mesh->verts.size(); kobject.numverts = mesh->verts.size();;
int numkeys = mesh->curve_keys.size(); kobject.patch_map_offset = 0;
kobject.attribute_map_offset = 0;
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);
/* Object flag. */ /* Object flag. */
if(ob->use_holdout) { if(ob->use_holdout) {
@ -486,7 +489,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene,
state.queue_start_object = 0; state.queue_start_object = 0;
state.object_flag = object_flag; 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) { if(state.need_motion == Scene::MOTION_PASS) {
state.objects_vector = dscene->objects_vector.alloc(OBJECT_VECTOR_SIZE*scene->objects.size()); 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; return;
} }
uint4* objects = (uint4*)dscene->objects.data(); KernelObject *kobjects = dscene->objects.data();
bool update = false; bool update = false;
int object_index = 0; int object_index = 0;
foreach(Object *object, scene->objects) { foreach(Object *object, scene->objects) {
Mesh* mesh = object->mesh; Mesh* mesh = object->mesh;
int offset = object_index*OBJECT_SIZE + 15;
if(mesh->patch_table) { if(mesh->patch_table) {
uint patch_map_offset = 2*(mesh->patch_table_offset + mesh->patch_table->total_size() - 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; mesh->patch_table->num_nodes * PATCH_NODE_SIZE) - mesh->patch_offset;
if(objects[offset].x != patch_map_offset) { if(kobjects[object_index].patch_map_offset != patch_map_offset) {
objects[offset].x = patch_map_offset; kobjects[object_index].patch_map_offset = patch_map_offset;
update = true; update = true;
} }
} }
if(objects[offset].y != mesh->attr_map_offset) { if(kobjects[object_index].attribute_map_offset != mesh->attr_map_offset) {
objects[offset].y = mesh->attr_map_offset; kobjects[object_index].attribute_map_offset = mesh->attr_map_offset;
update = true; update = true;
} }

@ -134,7 +134,7 @@ protected:
/* Packed object arrays. Those will be filled in. */ /* Packed object arrays. Those will be filled in. */
uint *object_flag; uint *object_flag;
float4 *objects; KernelObject *objects;
float4 *objects_vector; float4 *objects_vector;
/* Flags which will be synchronized to Integrator. */ /* Flags which will be synchronized to Integrator. */

@ -86,7 +86,7 @@ public:
device_vector<uint> patches; device_vector<uint> patches;
/* objects */ /* objects */
device_vector<float4> objects; device_vector<KernelObject> objects;
device_vector<float4> objects_vector; device_vector<float4> objects_vector;
/* attributes */ /* attributes */