Commit: cac3d4d16691d77e8e01f158be07d182e56e9755
Author: Brecht Van Lommel
Date:   Sun Nov 5 17:40:36 2017 +0100
Branches: master
https://developer.blender.org/rBcac3d4d16691d77e8e01f158be07d182e56e9755

Cycles: fix inefficient attribute map storage, saves 615MB in victor scene.

===================================================================

M       intern/cycles/kernel/geom/geom_attribute.h
M       intern/cycles/kernel/geom/geom_motion_curve.h
M       intern/cycles/kernel/geom/geom_motion_triangle.h
M       intern/cycles/kernel/kernel_types.h
M       intern/cycles/render/mesh.cpp
M       intern/cycles/render/mesh.h
M       intern/cycles/render/object.cpp
M       intern/cycles/render/object.h

===================================================================

diff --git a/intern/cycles/kernel/geom/geom_attribute.h 
b/intern/cycles/kernel/geom/geom_attribute.h
index cc62192ef21..18f5c813cc8 100644
--- a/intern/cycles/kernel/geom/geom_attribute.h
+++ b/intern/cycles/kernel/geom/geom_attribute.h
@@ -51,14 +51,21 @@ ccl_device_inline AttributeDescriptor attribute_not_found()
 
 /* Find attribute based on ID */
 
+ccl_device_inline uint object_attribute_map_offset(KernelGlobals *kg, int 
object)
+{
+       int offset = object*OBJECT_SIZE + 11;
+       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)
 {
-       if(sd->object == PRIM_NONE) {
+       if(sd->object == OBJECT_NONE) {
                return attribute_not_found();
        }
 
        /* for SVM, find attribute by unique id */
-       uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+       uint attr_offset = object_attribute_map_offset(kg, sd->object);
        attr_offset += attribute_primitive_type(kg, sd);
        uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
        
diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h 
b/intern/cycles/kernel/geom/geom_motion_curve.h
index 119bdb2f15c..fad29e431ec 100644
--- a/intern/cycles/kernel/geom/geom_motion_curve.h
+++ b/intern/cycles/kernel/geom/geom_motion_curve.h
@@ -33,7 +33,7 @@ ccl_device_inline int 
find_attribute_curve_motion(KernelGlobals *kg, int object,
         * zero iterations and rendering is really slow with motion curves. For 
until other
         * areas are speed up it's probably not so crucial to optimize this out.
         */
-       uint attr_offset = object*kernel_data.bvh.attributes_map_stride + 
ATTR_PRIM_CURVE;
+       uint attr_offset = object_attribute_map_offset(kg, object) + 
ATTR_PRIM_CURVE;
        uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
 
        while(attr_map.x != id) {
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h 
b/intern/cycles/kernel/geom/geom_motion_triangle.h
index 4e84aa97776..cd28b75c22c 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle.h
@@ -32,7 +32,7 @@ CCL_NAMESPACE_BEGIN
 ccl_device_inline int find_attribute_motion(KernelGlobals *kg, int object, 
uint id, AttributeElement *elem)
 {
        /* todo: find a better (faster) solution for this, maybe store offset 
per object */
-       uint attr_offset = object*kernel_data.bvh.attributes_map_stride;
+       uint attr_offset = object_attribute_map_offset(kg, object);
        uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
        
        while(attr_map.x != id) {
diff --git a/intern/cycles/kernel/kernel_types.h 
b/intern/cycles/kernel/kernel_types.h
index 49ec6d97f28..d1733d8a6e7 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1295,13 +1295,12 @@ static_assert_align(KernelIntegrator, 16);
 typedef struct KernelBVH {
        /* root node */
        int root;
-       int attributes_map_stride;
        int have_motion;
        int have_curves;
        int have_instancing;
        int use_qbvh;
        int use_bvh_steps;
-       int pad1;
+       int pad1, pad2;
 } KernelBVH;
 static_assert_align(KernelBVH, 16);
 
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 75bdf71616f..189ba80ad2a 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -436,6 +436,8 @@ Mesh::Mesh()
        face_offset = 0;
        corner_offset = 0;
 
+       attr_map_offset = 0;
+
        num_subd_verts = 0;
 
        attributes.triangle_mesh = this;
@@ -1258,33 +1260,27 @@ void MeshManager::update_svm_attributes(Device *, 
DeviceScene *dscene, Scene *sc
         * attribute, based on a unique shader attribute id. */
 
        /* compute array stride */
-       int attr_map_stride = 0;
+       int attr_map_size = 0;
 
-       for(size_t i = 0; i < scene->meshes.size(); i++)
-               attr_map_stride = max(attr_map_stride, 
(mesh_attributes[i].size() + 1)*ATTR_PRIM_TYPES);
+       for(size_t i = 0; i < scene->meshes.size(); i++) {
+               Mesh *mesh = scene->meshes[i];
+               mesh->attr_map_offset = attr_map_size;
+               attr_map_size += (mesh_attributes[i].size() + 
1)*ATTR_PRIM_TYPES;
+       }
 
-       if(attr_map_stride == 0)
+       if(attr_map_size == 0)
                return;
 
        /* create attribute map */
-       uint4 *attr_map = 
dscene->attributes_map.alloc(attr_map_stride*scene->objects.size());
+       uint4 *attr_map = 
dscene->attributes_map.alloc(attr_map_size*scene->meshes.size());
        memset(attr_map, 0, dscene->attributes_map.size()*sizeof(uint));
 
-       for(size_t i = 0; i < scene->objects.size(); i++) {
-               Object *object = scene->objects[i];
-               Mesh *mesh = object->mesh;
-
-               /* find mesh attributes */
-               size_t j;
-
-               for(j = 0; j < scene->meshes.size(); j++)
-                       if(scene->meshes[j] == mesh)
-                               break;
-
-               AttributeRequestSet& attributes = mesh_attributes[j];
+       for(size_t i = 0; i < scene->meshes.size(); i++) {
+               Mesh *mesh = scene->meshes[i];
+               AttributeRequestSet& attributes = mesh_attributes[i];
 
                /* set object attributes */
-               int index = i*attr_map_stride;
+               int index = mesh->attr_map_offset;
 
                foreach(AttributeRequest& req, attributes.requests) {
                        uint id;
@@ -1358,7 +1354,6 @@ void MeshManager::update_svm_attributes(Device *, 
DeviceScene *dscene, Scene *sc
        }
 
        /* copy to device */
-       dscene->data.bvh.attributes_map_stride = attr_map_stride;
        dscene->attributes_map.copy_to_device();
 }
 
@@ -1625,6 +1620,12 @@ void MeshManager::device_update_attributes(Device 
*device, DeviceScene *dscene,
        if(dscene->attributes_uchar4.size()) {
                dscene->attributes_uchar4.copy_to_device();
        }
+
+       if(progress.get_cancel()) return;
+
+       /* After mesh attributes and patch tables have been copied to device 
memory,
+        * we need to update offsets in the objects. */
+       scene->object_manager->device_update_mesh_offsets(device, dscene, 
scene);
 }
 
 void MeshManager::mesh_calc_offset(Scene *scene)
@@ -2042,10 +2043,6 @@ void MeshManager::device_update(Device *device, 
DeviceScene *dscene, Scene *scen
        }
        if(progress.get_cancel()) return;
 
-       /* after mesh data has been copied to device memory we need to update
-        * offsets for patch tables as this can't be known before hand */
-       scene->object_manager->device_update_patch_map_offsets(device, dscene, 
scene);
-
        device_update_attributes(device, dscene, scene, progress);
        if(progress.get_cancel()) return;
 
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 30f5e9063e6..07d8bbdbf31 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -250,6 +250,8 @@ public:
        size_t face_offset;
        size_t corner_offset;
 
+       size_t attr_map_offset;
+
        size_t num_subd_verts;
 
        /* Functions */
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 3b93b0c0d1e..a12a0d297f0 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -641,7 +641,7 @@ void ObjectManager::device_update_flags(Device *,
        dscene->object_flag.copy_to_device();
 }
 
-void ObjectManager::device_update_patch_map_offsets(Device *, DeviceScene 
*dscene, Scene *scene)
+void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, 
Scene *scene)
 {
        if(scene->objects.size() == 0) {
                return;
@@ -650,12 +650,11 @@ void 
ObjectManager::device_update_patch_map_offsets(Device *, DeviceScene *dscen
        uint4* objects = (uint4*)dscene->objects.data();
 
        bool update = false;
-
        int object_index = 0;
-       foreach(Object *object, scene->objects) {
-               int offset = object_index*OBJECT_SIZE + 11;
 
+       foreach(Object *object, scene->objects) {
                Mesh* mesh = object->mesh;
+               int offset = object_index*OBJECT_SIZE + 11;
 
                if(mesh->patch_table) {
                        uint patch_map_offset = 2*(mesh->patch_table_offset + 
mesh->patch_table->total_size() -
@@ -667,6 +666,11 @@ void ObjectManager::device_update_patch_map_offsets(Device 
*, DeviceScene *dscen
                        }
                }
 
+               if(objects[offset].y != mesh->attr_map_offset) {
+                       objects[offset].y = mesh->attr_map_offset;
+                       update = true;
+               }
+
                object_index++;
        }
 
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 6927bbfe4c7..9f86c342acd 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -104,7 +104,7 @@ public:
                                 Scene *scene,
                                 Progress& progress,
                                 bool bounds_valid = true);
-       void device_update_patch_map_offsets(Device *device, DeviceScene 
*dscene, Scene *scene);
+       void device_update_mesh_offsets(Device *device, DeviceScene *dscene, 
Scene *scene);
 
        void device_free(Device *device, DeviceScene *dscene);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to