Cycles: reduce memory usage of instanced objects by about 40%, as long as the
motion vector pass is not enabled.
This commit is contained in:
@@ -20,11 +20,16 @@ CCL_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
enum ObjectTransform {
|
enum ObjectTransform {
|
||||||
OBJECT_TRANSFORM = 0,
|
OBJECT_TRANSFORM = 0,
|
||||||
OBJECT_INVERSE_TRANSFORM = 3,
|
OBJECT_TRANSFORM_MOTION_PRE = 0,
|
||||||
OBJECT_PROPERTIES = 6,
|
OBJECT_INVERSE_TRANSFORM = 4,
|
||||||
OBJECT_TRANSFORM_MOTION_PRE = 8,
|
OBJECT_TRANSFORM_MOTION_POST = 4,
|
||||||
OBJECT_TRANSFORM_MOTION_POST = 12,
|
OBJECT_PROPERTIES = 8,
|
||||||
OBJECT_DUPLI = 16
|
OBJECT_DUPLI = 9
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ObjectVectorTransform {
|
||||||
|
OBJECT_VECTOR_MOTION_PRE = 0,
|
||||||
|
OBJECT_VECTOR_MOTION_POST = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
|
__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
|
||||||
@@ -40,6 +45,19 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object,
|
|||||||
return tfm;
|
return tfm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type)
|
||||||
|
{
|
||||||
|
int offset = object*OBJECT_VECTOR_SIZE + (int)type;
|
||||||
|
|
||||||
|
Transform tfm;
|
||||||
|
tfm.x = kernel_tex_fetch(__objects_vector, offset + 0);
|
||||||
|
tfm.y = kernel_tex_fetch(__objects_vector, offset + 1);
|
||||||
|
tfm.z = kernel_tex_fetch(__objects_vector, offset + 2);
|
||||||
|
tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
return tfm;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __OBJECT_MOTION__
|
#ifdef __OBJECT_MOTION__
|
||||||
__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
|
__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
|
||||||
{
|
{
|
||||||
|
@@ -34,6 +34,7 @@ KERNEL_TEX(uint, texture_uint, __object_node)
|
|||||||
|
|
||||||
/* objects */
|
/* objects */
|
||||||
KERNEL_TEX(float4, texture_float4, __objects)
|
KERNEL_TEX(float4, texture_float4, __objects)
|
||||||
|
KERNEL_TEX(float4, texture_float4, __objects_vector)
|
||||||
|
|
||||||
/* triangles */
|
/* triangles */
|
||||||
KERNEL_TEX(float4, texture_float4, __tri_normal)
|
KERNEL_TEX(float4, texture_float4, __tri_normal)
|
||||||
|
@@ -209,10 +209,10 @@ __device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd)
|
|||||||
* transformation was set match the world/object space of motion_pre/post */
|
* transformation was set match the world/object space of motion_pre/post */
|
||||||
Transform tfm;
|
Transform tfm;
|
||||||
|
|
||||||
tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_PRE);
|
tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_PRE);
|
||||||
motion_pre = transform_point(&tfm, motion_pre);
|
motion_pre = transform_point(&tfm, motion_pre);
|
||||||
|
|
||||||
tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_POST);
|
tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_POST);
|
||||||
motion_post = transform_point(&tfm, motion_post);
|
motion_post = transform_point(&tfm, motion_post);
|
||||||
|
|
||||||
float3 P;
|
float3 P;
|
||||||
|
@@ -29,7 +29,8 @@
|
|||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/* constants */
|
/* constants */
|
||||||
#define OBJECT_SIZE 18
|
#define OBJECT_SIZE 11
|
||||||
|
#define OBJECT_VECTOR_SIZE 6
|
||||||
#define LIGHT_SIZE 4
|
#define LIGHT_SIZE 4
|
||||||
#define FILTER_TABLE_SIZE 256
|
#define FILTER_TABLE_SIZE 256
|
||||||
#define RAMP_TABLE_SIZE 256
|
#define RAMP_TABLE_SIZE 256
|
||||||
|
@@ -150,12 +150,17 @@ ObjectManager::~ObjectManager()
|
|||||||
|
|
||||||
void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, uint *object_flag, Progress& progress)
|
void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, uint *object_flag, Progress& progress)
|
||||||
{
|
{
|
||||||
float4 *objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
|
float4 *objects;
|
||||||
|
float4 *objects_vector = NULL;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
map<Mesh*, float> surface_area_map;
|
map<Mesh*, float> surface_area_map;
|
||||||
Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
|
Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
|
||||||
bool have_motion = false;
|
bool have_motion = false;
|
||||||
|
|
||||||
|
objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
|
||||||
|
if(need_motion == Scene::MOTION_PASS)
|
||||||
|
objects_vector = dscene->objects_vector.resize(OBJECT_VECTOR_SIZE*scene->objects.size());
|
||||||
|
|
||||||
foreach(Object *ob, scene->objects) {
|
foreach(Object *ob, scene->objects) {
|
||||||
Mesh *mesh = ob->mesh;
|
Mesh *mesh = ob->mesh;
|
||||||
uint flag = 0;
|
uint flag = 0;
|
||||||
@@ -205,8 +210,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
|||||||
int offset = i*OBJECT_SIZE;
|
int offset = i*OBJECT_SIZE;
|
||||||
|
|
||||||
memcpy(&objects[offset], &tfm, sizeof(float4)*3);
|
memcpy(&objects[offset], &tfm, sizeof(float4)*3);
|
||||||
memcpy(&objects[offset+3], &itfm, sizeof(float4)*3);
|
memcpy(&objects[offset+4], &itfm, sizeof(float4)*3);
|
||||||
objects[offset+6] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
|
objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
|
||||||
|
|
||||||
if(need_motion == Scene::MOTION_PASS) {
|
if(need_motion == Scene::MOTION_PASS) {
|
||||||
/* motion transformations, is world/object space depending if mesh
|
/* motion transformations, is world/object space depending if mesh
|
||||||
@@ -220,8 +225,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
|||||||
if(!mesh->attributes.find(ATTR_STD_MOTION_POST))
|
if(!mesh->attributes.find(ATTR_STD_MOTION_POST))
|
||||||
mtfm_post = mtfm_post * itfm;
|
mtfm_post = mtfm_post * itfm;
|
||||||
|
|
||||||
memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
|
memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+0], &mtfm_pre, sizeof(float4)*3);
|
||||||
memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
|
memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+3], &mtfm_post, sizeof(float4)*3);
|
||||||
}
|
}
|
||||||
#ifdef __OBJECT_MOTION__
|
#ifdef __OBJECT_MOTION__
|
||||||
else if(need_motion == Scene::MOTION_BLUR) {
|
else if(need_motion == Scene::MOTION_BLUR) {
|
||||||
@@ -230,20 +235,16 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
|||||||
DecompMotionTransform decomp;
|
DecompMotionTransform decomp;
|
||||||
|
|
||||||
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
|
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
|
||||||
memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
|
memcpy(&objects[offset], &decomp, sizeof(float4)*8);
|
||||||
flag |= SD_OBJECT_MOTION;
|
flag |= SD_OBJECT_MOTION;
|
||||||
have_motion = true;
|
have_motion = true;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
float4 no_motion = make_float4(FLT_MAX);
|
|
||||||
memcpy(&objects[offset+8], &no_motion, sizeof(float4)*8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* dupli object coords */
|
/* dupli object coords */
|
||||||
objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
|
objects[offset+9] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
|
||||||
objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
|
objects[offset+10] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
|
||||||
|
|
||||||
/* object flag */
|
/* object flag */
|
||||||
if(ob->use_holdout)
|
if(ob->use_holdout)
|
||||||
@@ -256,6 +257,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
|||||||
}
|
}
|
||||||
|
|
||||||
device->tex_alloc("__objects", dscene->objects);
|
device->tex_alloc("__objects", dscene->objects);
|
||||||
|
if(need_motion == Scene::MOTION_PASS)
|
||||||
|
device->tex_alloc("__objects_vector", dscene->objects_vector);
|
||||||
|
|
||||||
dscene->data.bvh.have_motion = have_motion;
|
dscene->data.bvh.have_motion = have_motion;
|
||||||
}
|
}
|
||||||
@@ -297,6 +300,9 @@ void ObjectManager::device_free(Device *device, DeviceScene *dscene)
|
|||||||
device->tex_free(dscene->objects);
|
device->tex_free(dscene->objects);
|
||||||
dscene->objects.clear();
|
dscene->objects.clear();
|
||||||
|
|
||||||
|
device->tex_free(dscene->objects_vector);
|
||||||
|
dscene->objects_vector.clear();
|
||||||
|
|
||||||
device->tex_free(dscene->object_flag);
|
device->tex_free(dscene->object_flag);
|
||||||
dscene->object_flag.clear();
|
dscene->object_flag.clear();
|
||||||
}
|
}
|
||||||
|
@@ -74,6 +74,7 @@ public:
|
|||||||
|
|
||||||
/* objects */
|
/* objects */
|
||||||
device_vector<float4> objects;
|
device_vector<float4> objects;
|
||||||
|
device_vector<float4> objects_vector;
|
||||||
|
|
||||||
/* attributes */
|
/* attributes */
|
||||||
device_vector<uint4> attributes_map;
|
device_vector<uint4> attributes_map;
|
||||||
|
Reference in New Issue
Block a user