Commit: 593af14c87a8a04544c66f5d2d243bbbac6a832b
Author: Sergey Sharybin
Date:   Wed Jun 15 10:47:46 2016 +0200
Branches: cycles_bvh
https://developer.blender.org/rB593af14c87a8a04544c66f5d2d243bbbac6a832b

Cycles: Fix crash when true displacement is used

Not fastest code from device_update() timing point of view, but
keeps memory usage same small as final renders.

At this point we are back to full test suit pass when QBVH is used.

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

M       intern/cycles/render/mesh.cpp
M       intern/cycles/render/mesh.h

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

diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index d1de262..661719e 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1115,7 +1115,11 @@ void MeshManager::mesh_calc_offset(Scene *scene)
        }
 }
 
-void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, 
Scene *scene, Progress& progress)
+void MeshManager::device_update_mesh(Device *device,
+                                     DeviceScene *dscene,
+                                     Scene *scene,
+                                     bool for_displacement,
+                                     Progress& progress)
 {
        /* Count. */
        size_t vert_size = 0;
@@ -1129,15 +1133,25 @@ void MeshManager::device_update_mesh(Device *device, 
DeviceScene *dscene, Scene
                curve_size += mesh->num_curves();
        }
        /* Create mapping from triangle to primitive triangle array. */
-       vector<uint> tri_prim_index;
-       PackedBVH& pack = bvh->pack;
-       tri_prim_index.resize(tri_size);
-       for(size_t i = 0; i < tri_size; ++i) {
-               tri_prim_index[i] = -1;
+       vector<uint> tri_prim_index(tri_size);
+       if(for_displacement) {
+               /* For displacement kernels we do some trickery to make them 
believe
+                * we've got all required data ready. However, that data is 
different
+                * from final render kernels since we don't have BVH yet, so 
can't
+                * really use same semantic of arrays.
+                */
+               foreach(Mesh *mesh, scene->meshes) {
+                       for(size_t i = 0; i < mesh->num_triangles(); ++i) {
+                               tri_prim_index[i + mesh->tri_offset] = 3 * (i + 
mesh->tri_offset);
+                       }
+               }
        }
-       for(size_t i = 0; i < pack.prim_index.size(); ++i) {
-               if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
-                       tri_prim_index[pack.prim_index[i]] = 
pack.prim_tri_index[i];
+       else {
+               PackedBVH& pack = bvh->pack;
+               for(size_t i = 0; i < pack.prim_index.size(); ++i) {
+                       if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
+                               tri_prim_index[pack.prim_index[i]] = 
pack.prim_tri_index[i];
+                       }
                }
        }
        /* Fill in all the arrays. */
@@ -1181,6 +1195,19 @@ void MeshManager::device_update_mesh(Device *device, 
DeviceScene *dscene, Scene
                device->tex_alloc("__curve_keys", dscene->curve_keys);
                device->tex_alloc("__curves", dscene->curves);
        }
+       if(for_displacement) {
+               float4 *prim_tri_verts = dscene->prim_tri_verts.resize(tri_size 
* 3);
+               foreach(Mesh *mesh, scene->meshes) {
+                       for(size_t i = 0; i < mesh->num_triangles(); ++i) {
+                               Mesh::Triangle t = mesh->get_triangle(i);
+                               size_t offset = 3 * (i + mesh->tri_offset);
+                               prim_tri_verts[offset + 0] = 
float3_to_float4(mesh->verts[t.v[0]]);
+                               prim_tri_verts[offset + 1] = 
float3_to_float4(mesh->verts[t.v[1]]);
+                               prim_tri_verts[offset + 2] = 
float3_to_float4(mesh->verts[t.v[2]]);
+                       }
+               }
+               device->tex_alloc("__prim_tri_verts", dscene->prim_tri_verts);
+       }
 }
 
 void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene 
*scene, Progress& progress)
@@ -1327,7 +1354,7 @@ void MeshManager::device_update(Device *device, 
DeviceScene *dscene, Scene *scen
 
        VLOG(1) << "Total " << scene->meshes.size() << " meshes.";
 
-       /* update normals */
+       /* Update normals. */
        foreach(Mesh *mesh, scene->meshes) {
                foreach(Shader *shader, mesh->used_shaders) {
                        if(shader->need_update_attributes)
@@ -1343,17 +1370,17 @@ void MeshManager::device_update(Device *device, 
DeviceScene *dscene, Scene *scen
        }
 
        /* Update images needed for true displacement. */
-       bool need_displacement_images = false;
+       bool true_displacement_used = false;
        bool old_need_object_flags_update = false;
        foreach(Mesh *mesh, scene->meshes) {
                if(mesh->need_update &&
                   mesh->displacement_method != Mesh::DISPLACE_BUMP)
                {
-                       need_displacement_images = true;
+                       true_displacement_used = true;
                        break;
                }
        }
-       if(need_displacement_images) {
+       if(true_displacement_used) {
                VLOG(1) << "Updating images used for true displacement.";
                device_update_displacement_images(device, dscene, scene, 
progress);
                old_need_object_flags_update = 
scene->object_manager->need_flags_update;
@@ -1364,48 +1391,47 @@ void MeshManager::device_update(Device *device, 
DeviceScene *dscene, Scene *scen
                                                           false);
        }
 
-       /* device update */
+       /* Device update. */
        device_free(device, dscene);
 
        mesh_calc_offset(scene);
+       if(true_displacement_used) {
+               device_update_mesh(device, dscene, scene, true, progress);
+       }
        if(progress.get_cancel()) return;
 
        device_update_attributes(device, dscene, scene, progress);
        if(progress.get_cancel()) return;
 
-       /* update displacement */
+       /* Update displacement. */
        bool displacement_done = false;
-
-       /* TODO(sergey): With current arrays formulation true displacement will
-        * crash. Need some magic to avoid this.
-        */
-       foreach(Mesh *mesh, scene->meshes)
-               if(mesh->need_update && displace(device, dscene, scene, mesh, 
progress))
+       foreach(Mesh *mesh, scene->meshes) {
+               if(mesh->need_update &&
+                  displace(device, dscene, scene, mesh, progress))
+               {
                        displacement_done = true;
+               }
+       }
 
-       /* todo: properly handle cancel halfway displacement */
+       /* TODO: properly handle cancel halfway displacement */
        if(progress.get_cancel()) return;
 
-       /* device re-update after displacement */
+       /* Device re-update after displacement. */
        if(displacement_done) {
                device_free(device, dscene);
 
-               device_update_mesh(device, dscene, scene, progress);
-               if(progress.get_cancel()) return;
-
                device_update_attributes(device, dscene, scene, progress);
                if(progress.get_cancel()) return;
        }
 
-       /* update bvh */
+       /* Update bvh. */
        size_t i = 0, num_bvh = 0;
-
-       foreach(Mesh *mesh, scene->meshes)
-               if(mesh->need_update && mesh->need_build_bvh())
+       foreach(Mesh *mesh, scene->meshes) {
+               if(mesh->need_update && mesh->need_build_bvh()) {
                        num_bvh++;
-
+               }
+       }
        TaskPool pool;
-
        foreach(Mesh *mesh, scene->meshes) {
                if(mesh->need_update) {
                        pool.push(function_bind(&Mesh::compute_bvh,
@@ -1420,14 +1446,14 @@ void MeshManager::device_update(Device *device, 
DeviceScene *dscene, Scene *scen
                        }
                }
        }
-
        TaskPool::Summary summary;
        pool.wait_work(&summary);
        VLOG(2) << "Objects BVH build pool statistics:\n"
                << summary.full_report();
 
-       foreach(Shader *shader, scene->shaders)
+       foreach(Shader *shader, scene->shaders) {
                shader->need_update_attributes = false;
+       }
 
 #ifdef __OBJECT_MOTION__
        Scene::MotionType need_motion = 
scene->need_motion(device->info.advanced_shading);
@@ -1436,22 +1462,23 @@ void MeshManager::device_update(Device *device, 
DeviceScene *dscene, Scene *scen
        bool motion_blur = false;
 #endif
 
-       /* update obejcts */
+       /* Update objects. */
        vector<Object *> volume_objects;
-       foreach(Object *object, scene->objects)
+       foreach(Object *object, scene->objects) {
                object->compute_bounds(motion_blur);
+       }
 
        if(progress.get_cancel()) return;
 
        device_update_bvh(device, dscene, scene, progress);
        if(progress.get_cancel()) return;
 
-       device_update_mesh(device, dscene, scene, progress);
+       device_update_mesh(device, dscene, scene, false, progress);
        if(progress.get_cancel()) return;
 
        need_update = false;
 
-       if(need_displacement_images) {
+       if(true_displacement_used) {
                /* Re-tag flags for update, so they're re-evaluated
                 * for meshes with correct bounding boxes.
                 *
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index a091c45..0aea555 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -238,11 +238,31 @@ protected:
        /* Calculate verts/triangles/curves offsets in global arrays. */
        void mesh_calc_offset(Scene *scene);
 
-       void device_update_object(Device *device, DeviceScene *dscene, Scene 
*scene, Progress& progress);
-       void device_update_mesh(Device *device, DeviceScene *dscene, Scene 
*scene, Progress& progress);
-       void device_update_attributes(Device *device, DeviceScene *dscene, 
Scene *scene, Progress& progress);
-       void device_update_bvh(Device *device, DeviceScene *dscene, Scene 
*scene, Progress& progress);
-       void device_update_displacement_images(Device *device, DeviceScene 
*dscene, Scene *scene, Progress& progress);
+       void device_update_object(Device *device,
+                                 DeviceScene *dscene,
+                                 Scene *scene,
+                                 Progress& progress);
+
+       void device_update_mesh(Device *device,
+                               DeviceScene *dscene,
+                               Scene *scene,
+                               bool for_displacement,
+                               Progress& progress);
+
+       void device_update_attributes(Device *device,
+                                     DeviceScene *dscene,
+                                     Scene *scene,
+                                     Progress& progress);
+
+       void device_update_bvh(Device *device,
+                              DeviceScene *dscene,
+                              Scene *scene,
+                              Progress& progress);
+
+       void device_update_displacement_images(Device *device,
+                                              DeviceScene *dscene,
+                                              Scene *scene,
+                                              Progress& progress);
 };
 
 CCL_NAMESPACE_END

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

Reply via email to