diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-05-10 19:23:32 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-05-14 03:40:43 +0300 |
commit | fce795415ade673dfbe4b176113c09a925150c71 (patch) | |
tree | 51f8a0cd9be5b2e108d4ad83812771f234467ad7 /intern/cycles/render/geometry.cpp | |
parent | 37570a73170e6cddc32ed0523b626bf0857cf068 (diff) |
Fix T87929: Cycles, missing update when visibility is modified
This issue originates from a missing BVH packing for visibility data
when it is modified.
To fix this, this adds update flags to the managers to carry the
modified visibility information from the Objects' modified flag to the
GeometryManager.
Another set of flags is added to determine which data need to be packed:
geometry, vertices, or visibility. Those flags are then used when
packing the primivites.
Reviewed By: brecht
Maniphest Tasks: T87929
Differential Revision: https://developer.blender.org/D11219
Diffstat (limited to 'intern/cycles/render/geometry.cpp')
-rw-r--r-- | intern/cycles/render/geometry.cpp | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp index bd2b8164cbb..a1bb8b35ca0 100644 --- a/intern/cycles/render/geometry.cpp +++ b/intern/cycles/render/geometry.cpp @@ -46,6 +46,12 @@ CCL_NAMESPACE_BEGIN /* Geometry */ +PackFlags operator |=(PackFlags &pack_flags, uint32_t value) +{ + pack_flags = (PackFlags)((uint32_t)pack_flags | value); + return pack_flags; +} + NODE_ABSTRACT_DEFINE(Geometry) { NodeType *type = NodeType::add("geometry_base", NULL); @@ -1235,7 +1241,16 @@ void GeometryManager::device_update_bvh(Device *device, const bool can_refit = scene->bvh != nullptr && (bparams.bvh_layout == BVHLayout::BVH_LAYOUT_OPTIX); - const bool pack_all = scene->bvh == nullptr; + + PackFlags pack_flags = PackFlags::PACK_NONE; + + if (scene->bvh == nullptr) { + pack_flags |= PackFlags::PACK_ALL; + } + + if (dscene->prim_visibility.is_modified()) { + pack_flags |= PackFlags::PACK_VISIBILITY; + } BVH *bvh = scene->bvh; if (!scene->bvh) { @@ -1273,10 +1288,14 @@ void GeometryManager::device_update_bvh(Device *device, pack.root_index = -1; - if (!pack_all) { + if (pack_flags != PackFlags::PACK_ALL) { /* if we do not need to recreate the BVH, then only the vertices are updated, so we can * safely retake the memory */ dscene->prim_tri_verts.give_data(pack.prim_tri_verts); + + if ((pack_flags & PackFlags::PACK_VISIBILITY) != 0) { + dscene->prim_visibility.give_data(pack.prim_visibility); + } } else { /* It is not strictly necessary to skip those resizes we if do not have to repack, as the OS @@ -1305,13 +1324,20 @@ void GeometryManager::device_update_bvh(Device *device, // Iterate over scene mesh list instead of objects, since 'optix_prim_offset' was calculated // based on that list, which may be ordered differently from the object list. foreach (Geometry *geom, scene->geometry) { - if (!pack_all && !geom->is_modified()) { + /* Make a copy of the pack_flags so the current geometry's flags do not pollute the others'. */ + PackFlags geom_pack_flags = pack_flags; + + if (geom->is_modified()) { + geom_pack_flags |= PackFlags::PACK_VERTICES; + } + + if (geom_pack_flags == PACK_NONE) { continue; } const pair<int, uint> &info = geometry_to_object_info[geom]; pool.push(function_bind( - &Geometry::pack_primitives, geom, &pack, info.first, info.second, pack_all)); + &Geometry::pack_primitives, geom, &pack, info.first, info.second, geom_pack_flags)); } pool.wait_work(); } @@ -1346,7 +1372,7 @@ void GeometryManager::device_update_bvh(Device *device, dscene->prim_type.steal_data(pack.prim_type); dscene->prim_type.copy_to_device(); } - if (pack.prim_visibility.size() && (dscene->prim_visibility.need_realloc() || has_bvh2_layout)) { + if (pack.prim_visibility.size() && (dscene->prim_visibility.is_modified() || has_bvh2_layout)) { dscene->prim_visibility.steal_data(pack.prim_visibility); dscene->prim_visibility.copy_to_device(); } @@ -1594,6 +1620,10 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro } } + if ((update_flags & VISIBILITY_MODIFIED) != 0) { + dscene->prim_visibility.tag_modified(); + } + if (device_update_flags & ATTR_FLOAT_NEEDS_REALLOC) { dscene->attributes_map.tag_realloc(); dscene->attributes_float.tag_realloc(); @@ -1920,7 +1950,7 @@ void GeometryManager::device_update(Device *device, * Also update the BVH if the transformations change, we cannot rely on tagging the Geometry * as modified in this case, as we may accumulate displacement if the vertices do not also * change. */ - bool need_update_scene_bvh = (scene->bvh == nullptr || (update_flags & TRANSFORM_MODIFIED) != 0); + bool need_update_scene_bvh = (scene->bvh == nullptr || (update_flags & (TRANSFORM_MODIFIED | VISIBILITY_MODIFIED)) != 0); { scoped_callback_timer timer([scene](double time) { if (scene->update_stats) { |