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