Geometry nodes output gets synced to cycles wrong. #92606

Closed
opened 2021-10-29 12:47:55 +02:00 by Martijn Versteegh · 25 comments

System Information
Operating system: Linux-5.4.0-89-generic-x86_64-with-glibc2.31 64 Bits
Graphics card: NVIDIA GeForce RTX 2060 SUPER/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 470.74

Blender Version
Broken: version: 3.1.0 Alpha, branch: Unknown, commit date: Unknown Unknown, hash: rBUnknown
Worked: N/A
Short description of error
When I toggle the boolean value in a switch node, the cycles viewport gets updated wrong. Sometimes my toggle gets ignored, sometimes another switch node in the same tree gets toggled as well or instead of the one I toggle.

Annoyingly this only happens on the 2 desktop machines I have access to (both nvidia gpus, but using cycles cpu mode) but not on my laptop.

Extra annoyingly this does not happen in debug build.
Exact steps for others to reproduce the error
[Please describe the exact steps needed to reproduce the issue]
[Based on the default startup or an attached .blend file (as simple as possible)]
Open this blender file.
curve-geonodes-probablecachingbug-report.blend
(When I started working on creatiung a testcase I thought it was maybe a caching bug, but I'm not so sure now, so ignore the filename)
Switch the view to rendered, optionally set cycles to cpu or cpu compute mode (it happens in both modes on my computer)
In the geometry nodes tree toggle the 'instance along curves' 'flip' input.

Because it doesn't happen on all computers I'll add a video here.
cycles-sync-bug.mp4
What exactly happens seems to change on recompile (after make update). It's not really something with my specific machine tough, because it also happens at my work machine. Both on the official beta build (from blender.org) as my own compile.

Toggling lots of times can sometimes randomly affect the other toggles in the tree (i.e. what happens is not always the same on every toggle) and once I even got a crash. Sadly I forget to copy the crashdump from the tmp dir before rebooting the machine, and I haven't been able to force a crash again.

**System Information** Operating system: Linux-5.4.0-89-generic-x86_64-with-glibc2.31 64 Bits Graphics card: NVIDIA GeForce RTX 2060 SUPER/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 470.74 **Blender Version** Broken: version: 3.1.0 Alpha, branch: Unknown, commit date: Unknown Unknown, hash: `rBUnknown` Worked: N/A **Short description of error** When I toggle the boolean value in a switch node, the cycles viewport gets updated wrong. Sometimes my toggle gets ignored, sometimes another switch node in the same tree gets toggled as well or instead of the one I toggle. Annoyingly this only happens on the 2 desktop machines I have access to (both nvidia gpus, but using cycles cpu mode) but *not* on my laptop. Extra annoyingly this does not happen in debug build. **Exact steps for others to reproduce the error** [Please describe the exact steps needed to reproduce the issue] [Based on the default startup or an attached .blend file (as simple as possible)] Open this blender file. [curve-geonodes-probablecachingbug-report.blend](https://archive.blender.org/developer/F11595178/curve-geonodes-probablecachingbug-report.blend) (When I started working on creatiung a testcase I thought it was maybe a caching bug, but I'm not so sure now, so ignore the filename) Switch the view to rendered, optionally set cycles to cpu or cpu compute mode (it happens in both modes on my computer) In the geometry nodes tree toggle the 'instance along curves' 'flip' input. Because it doesn't happen on all computers I'll add a video here. [cycles-sync-bug.mp4](https://archive.blender.org/developer/F11595343/cycles-sync-bug.mp4) What exactly happens seems to change on recompile (after make update). It's not really something with my specific machine tough, because it also happens at my work machine. Both on the official beta build (from blender.org) as my own compile. Toggling lots of times can sometimes randomly affect the other toggles in the tree (i.e. what happens is not always the same on every toggle) and once I even got a crash. Sadly I forget to copy the crashdump from the tmp dir before rebooting the machine, and I haven't been able to force a crash again.
Author
Member

Added subscriber: @Baardaap

Added subscriber: @Baardaap
Martijn Versteegh changed title from Geometry nodes output gets synced tyo cycles wrong. to Geometry nodes output gets synced to cycles wrong. 2021-10-29 12:48:13 +02:00
Author
Member

Added subscribers: @brecht, @HooglyBoogly

Added subscribers: @brecht, @HooglyBoogly
Author
Member

I added Brecht & Hans as subscribers, as I suspect it's some interplay between geonodes & cycles syncing. I hope that's ok? I'm not really sure about the etiquette here. Is it ok to add someone out of the blue?

I added Brecht & Hans as subscribers, as I suspect it's some interplay between geonodes & cycles syncing. I hope that's ok? I'm not really sure about the etiquette here. Is it ok to add someone out of the blue?
Author
Member

I did some poking around in inernal/cycles/blender/sync.cpp and made it unconditionally update various stuff. That had no effect whatsoever on the bug, so far.

I did some poking around in inernal/cycles/blender/sync.cpp and made it unconditionally update various stuff. That had no effect whatsoever on the bug, so far.
Author
Member

Added subscriber: @JacquesLucke
Removed subscriber: @brecht

Added subscriber: @JacquesLucke Removed subscriber: @brecht
Author
Member

I did a long debugging session today with valgrind+drd (thread debugging) and memcheck.

and concluded the following:

blender::nodes::geo_node_curve_to_mesh_exec

runs at the same time as

blender::draw::mesh_extract_render_data_node_exec(void*) (draw_cache_extract_mesh.cc:537)

This needs locking somehow, as it starts sending stuff to the renderer while geonodes is generating the geometry.

I'm fairly certain this is the cause of the weirdness I'm seeing. But I'm not really sure how to proceed.

p.s. I removed Brecht from the subscribers, as it's clearly not a cycles problem. I added Jacques Lucke in the hope he has any insights in this matter.

I did a long debugging session today with valgrind+drd (thread debugging) and memcheck. and concluded the following: blender::nodes::geo_node_curve_to_mesh_exec runs at the same time as blender::draw::mesh_extract_render_data_node_exec(void*) (draw_cache_extract_mesh.cc:537) This needs locking somehow, as it starts sending stuff to the renderer while geonodes is generating the geometry. I'm fairly certain this is the cause of the weirdness I'm seeing. But I'm not really sure how to proceed. p.s. I removed Brecht from the subscribers, as it's clearly not a cycles problem. I added Jacques Lucke in the hope he has any insights in this matter.
Author
Member

The relevant DRD output, for those who know how to read it.


==178303== Conflicting load by thread 18 at 0x4b4241b8 size 8
==178303==    at 0x3F6B5DD: customdata_typemap_is_valid (customdata.c:2093)
==178303==    by 0x3F6BF07: CustomData_get_layer_index (customdata.c:2319)
==178303==    by 0x3F6D813: CustomData_has_layer (customdata.c:2767)
==178303==    by 0x3F6CC95: customData_add_layer__internal (customdata.c:2543)
==178303==    by 0x3F6D319: CustomData_add_layer (customdata.c:2645)
==178303==    by 0x3A91C44: BKE_mesh_ensure_normals_for_display (mesh_normals.cc:373)
==178303==    by 0x4550442: mesh_render_data_update_normals (draw_cache_extract_mesh_render_data.c:386)
==178303==    by 0x454A510: blender::draw::mesh_extract_render_data_node_exec(void*) (draw_cache_extract_mesh.cc:537)
==178303==    by 0x10746445: TaskNode::run(tbb::flow::interface11::continue_msg) (task_graph.cc:94)
==178303==    by 0x107462CC: TaskNode::TaskNode(TaskGraph*, void (*)(void*), void*, void (*)(void*))::{lambda(tbb::flow::interface11::continue_msg)#1}::operator()(tbb::flow::interface11::continue_msg) const (task_graph.cc:70)
==178303==    by 0x107493F2: tbb::flow::interface11::internal::function_body_leaf<tbb::flow::interface11::continue_msg, tbb::flow::interface11::continue_msg, TaskNode::TaskNode(TaskGraph*, void (*)(void*), void*, void (*)(void*))::{lambda(tbb::flow::interface11::continue_msg)#1}>::operator()(tbb::flow::interface11::continue_msg const&) (_flow_graph_body_impl.h:146)
==178303==    by 0x10749A60: tbb::flow::interface11::internal::continue_input<tbb::flow::interface11::continue_msg, tbb::flow::interface11::internal::Policy<void> >::apply_body_bypass(tbb::flow::interface11::continue_msg) (_flow_graph_node_impl.h:821)
==178303== Address 0x4b4241b8 is at offset 1144 from 0x4b423d40. Allocation context:
==178303==    at 0x19FDB0B9: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_drd-amd64-linux.so)
==178303==    by 0x1075B6D7: MEM_lockfree_callocN (mallocn_lockfree_impl.c:236)
==178303==    by 0x3A5EFFB: BKE_libblock_alloc_notest (lib_id.c:1095)
==178303==    by 0x3A5F121: BKE_libblock_alloc (lib_id.c:1113)
==178303==    by 0x3A8BF4A: BKE_mesh_new_nomain (mesh.c:977)
==178303==    by 0x40B711E: blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool) (curve_to_mesh_convert.cc:707)
==178303==    by 0x496A2A4: blender::nodes::geometry_set_curve_to_mesh(GeometrySet&, GeometrySet const&, bool) (node_geo_curve_to_mesh.cc:52)
==178303==    by 0x496A321: blender::nodes::geo_node_curve_to_mesh_exec(blender::nodes::GeoNodeExecParams)::{lambda(GeometrySet&)#1}::operator()(GeometrySet&) const (node_geo_curve_to_mesh.cc:67)
==178303==    by 0x496A632: void blender::FunctionRef<void (GeometrySet&)>::callback_fn<blender::nodes::geo_node_curve_to_mesh_exec(blender::nodes::GeoNodeExecParams)::{lambda(GeometrySet&)#1}>(long, GeometrySet&) (BLI_function_ref.hh:107)
==178303==    by 0x4049A23: blender::FunctionRef<void (GeometrySet&)>::operator()(GeometrySet&) const (BLI_function_ref.hh:144)
==178303==    by 0x4047013: GeometrySet::modify_geometry_sets(blender::FunctionRef<void (GeometrySet&)>)::{lambda(GeometrySet*)#1}::operator()(GeometrySet*) const (geometry_set.cc:593)
==178303==    by 0x40483B6: tbb::internal::parallel_for_each_body_for<GeometrySet::modify_geometry_sets(blender::FunctionRef<void (GeometrySet&)>)::{lambda(GeometrySet*)#1}, GeometrySet**>::operator()(tbb::blocked_range<GeometrySet::modify_geometry_sets(blender::FunctionRef<void (GeometrySet&)>)::{lambda(GeometrySet*)#1}>) const (parallel_for_each.h:51)
==178303== Other segment start (thread 1)
==178303==    at 0x19FE087C: pthread_mutex_unlock (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_drd-amd64-linux.so)
==178303==    by 0x3A2AD96: __gthread_mutex_unlock(pthread_mutex_t*) (gthr-default.h:779)
==178303==    by 0x3A2ADED: std::mutex::unlock() (std_mutex.h:118)
==178303==    by 0x3BEB896: std::lock_guard<std::mutex>::~lock_guard() (std_mutex.h:165)
==178303==    by 0x408EA0E: BezierSpline::control_point_offsets() const (spline_bezier.cc:519)
==178303==    by 0x408DD4D: BezierSpline::evaluated_points_size() const (spline_bezier.cc:395)
==178303==    by 0x40B5217: blender::bke::spline_extrude_vert_size(Spline const&, Spline const&) (curve_to_mesh_convert.cc:250)
==178303==    by 0x40B5690: blender::bke::calculate_result_offsets(blender::Span<std::unique_ptr<Spline, std::default_delete<Spline> > >, blender::Span<std::unique_ptr<Spline, std::default_delete<Spline> > >, bool) (curve_to_mesh_convert.cc:306)
==178303==    by 0x40B7094: blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool) (curve_to_mesh_convert.cc:702)
==178303==    by 0x496A2A4: blender::nodes::geometry_set_curve_to_mesh(GeometrySet&, GeometrySet const&, bool) (node_geo_curve_to_mesh.cc:52)
==178303==    by 0x496A321: blender::nodes::geo_node_curve_to_mesh_exec(blender::nodes::GeoNodeExecParams)::{lambda(GeometrySet&)#1}::operator()(GeometrySet&) const (node_geo_curve_to_mesh.cc:67)
==178303==    by 0x496A632: void blender::FunctionRef<void (GeometrySet&)>::callback_fn<blender::nodes::geo_node_curve_to_mesh_exec(blender::nodes::GeoNodeExecParams)::{lambda(GeometrySet&)#1}>(long, GeometrySet&) (BLI_function_ref.hh:107)
==178303== Other segment end (thread 1)
==178303==    at 0x19FDF82C: pthread_mutex_lock (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_drd-amd64-linux.so)
==178303==    by 0x3A2AD67: __gthread_mutex_lock(pthread_mutex_t*) (gthr-default.h:749)
==178303==    by 0x3A2ADBB: std::mutex::lock() (std_mutex.h:100)
==178303==    by 0x3BEB873: std::lock_guard<std::mutex>::lock_guard(std::mutex&) (std_mutex.h:159)
==178303==    by 0x408CC0A: BezierSpline::ensure_auto_handles() const (spline_bezier.cc:224)
==178303==    by 0x408F45C: BezierSpline::evaluated_positions() const (spline_bezier.cc:640)
==178303==    by 0x40B4D0D: blender::bke::spline_extrude_to_mesh_data(blender::bke::ResultInfo const&, bool, blender::MutableSpan<MVert>, blender::MutableSpan<MEdge>, blender::MutableSpan<MLoop>, blender::MutableSpan<MPoly>) (curve_to_mesh_convert.cc:219)
==178303==    by 0x40B6E03: blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const (curve_to_mesh_convert.cc:740)
==178303==    by 0x40B9F62: void blender::threading::parallel_for<blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}>(blender::IndexRange, long, blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1} const&)::{lambda(tbb::blocked_range<long> const&)#1}::operator()(tbb::blocked_range<long>) const (BLI_task.hh:72)
==178303==    by 0x40BF248: tbb::interface9::internal::start_for<tbb::blocked_range<long>, void blender::threading::parallel_for<blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}>(blender::IndexRange, long, blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1} const&)::{lambda(tbb::blocked_range<long> const&)#1}, tbb::auto_partitioner const>::run_body(tbb::blocked_range<long>&) (parallel_for.h:115)
==178303==    by 0x40BEDC9: void tbb::interface9::internal::dynamic_grainsize_mode<tbb::interface9::internal::adaptive_mode<tbb::interface9::internal::auto_partition_type> >::work_balance<tbb::interface9::internal::start_for<tbb::blocked_range<long>, void blender::threading::parallel_for<blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}>(blender::IndexRange, long, blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1} const&)::{lambda(tbb::blocked_range<long> const&)#1}, tbb::auto_partitioner const>, tbb::blocked_range<long> >({lambda(blender::IndexRange)#1}&, tbb::blocked_range<long>&) (partitioner.h:423)
==178303==    by 0x40BE9D1: void tbb::interface9::internal::partition_type_base<tbb::interface9::internal::auto_partition_type>::execute<tbb::interface9::internal::start_for<tbb::blocked_range<long>, void blender::threading::parallel_for<blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}>(blender::IndexRange, long, blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1} const&)::{lambda(tbb::blocked_range<long> const&)#1}, tbb::auto_partitioner const>, tbb::blocked_range<long> >({lambda(blender::IndexRange)#1}&, tbb::blocked_range<long>&) (partitioner.h:256)
==178303== 


The relevant DRD output, for those who know how to read it. ``` ==178303== Conflicting load by thread 18 at 0x4b4241b8 size 8 ==178303== at 0x3F6B5DD: customdata_typemap_is_valid (customdata.c:2093) ==178303== by 0x3F6BF07: CustomData_get_layer_index (customdata.c:2319) ==178303== by 0x3F6D813: CustomData_has_layer (customdata.c:2767) ==178303== by 0x3F6CC95: customData_add_layer__internal (customdata.c:2543) ==178303== by 0x3F6D319: CustomData_add_layer (customdata.c:2645) ==178303== by 0x3A91C44: BKE_mesh_ensure_normals_for_display (mesh_normals.cc:373) ==178303== by 0x4550442: mesh_render_data_update_normals (draw_cache_extract_mesh_render_data.c:386) ==178303== by 0x454A510: blender::draw::mesh_extract_render_data_node_exec(void*) (draw_cache_extract_mesh.cc:537) ==178303== by 0x10746445: TaskNode::run(tbb::flow::interface11::continue_msg) (task_graph.cc:94) ==178303== by 0x107462CC: TaskNode::TaskNode(TaskGraph*, void (*)(void*), void*, void (*)(void*))::{lambda(tbb::flow::interface11::continue_msg)#1}::operator()(tbb::flow::interface11::continue_msg) const (task_graph.cc:70) ==178303== by 0x107493F2: tbb::flow::interface11::internal::function_body_leaf<tbb::flow::interface11::continue_msg, tbb::flow::interface11::continue_msg, TaskNode::TaskNode(TaskGraph*, void (*)(void*), void*, void (*)(void*))::{lambda(tbb::flow::interface11::continue_msg)#1}>::operator()(tbb::flow::interface11::continue_msg const&) (_flow_graph_body_impl.h:146) ==178303== by 0x10749A60: tbb::flow::interface11::internal::continue_input<tbb::flow::interface11::continue_msg, tbb::flow::interface11::internal::Policy<void> >::apply_body_bypass(tbb::flow::interface11::continue_msg) (_flow_graph_node_impl.h:821) ==178303== Address 0x4b4241b8 is at offset 1144 from 0x4b423d40. Allocation context: ==178303== at 0x19FDB0B9: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_drd-amd64-linux.so) ==178303== by 0x1075B6D7: MEM_lockfree_callocN (mallocn_lockfree_impl.c:236) ==178303== by 0x3A5EFFB: BKE_libblock_alloc_notest (lib_id.c:1095) ==178303== by 0x3A5F121: BKE_libblock_alloc (lib_id.c:1113) ==178303== by 0x3A8BF4A: BKE_mesh_new_nomain (mesh.c:977) ==178303== by 0x40B711E: blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool) (curve_to_mesh_convert.cc:707) ==178303== by 0x496A2A4: blender::nodes::geometry_set_curve_to_mesh(GeometrySet&, GeometrySet const&, bool) (node_geo_curve_to_mesh.cc:52) ==178303== by 0x496A321: blender::nodes::geo_node_curve_to_mesh_exec(blender::nodes::GeoNodeExecParams)::{lambda(GeometrySet&)#1}::operator()(GeometrySet&) const (node_geo_curve_to_mesh.cc:67) ==178303== by 0x496A632: void blender::FunctionRef<void (GeometrySet&)>::callback_fn<blender::nodes::geo_node_curve_to_mesh_exec(blender::nodes::GeoNodeExecParams)::{lambda(GeometrySet&)#1}>(long, GeometrySet&) (BLI_function_ref.hh:107) ==178303== by 0x4049A23: blender::FunctionRef<void (GeometrySet&)>::operator()(GeometrySet&) const (BLI_function_ref.hh:144) ==178303== by 0x4047013: GeometrySet::modify_geometry_sets(blender::FunctionRef<void (GeometrySet&)>)::{lambda(GeometrySet*)#1}::operator()(GeometrySet*) const (geometry_set.cc:593) ==178303== by 0x40483B6: tbb::internal::parallel_for_each_body_for<GeometrySet::modify_geometry_sets(blender::FunctionRef<void (GeometrySet&)>)::{lambda(GeometrySet*)#1}, GeometrySet**>::operator()(tbb::blocked_range<GeometrySet::modify_geometry_sets(blender::FunctionRef<void (GeometrySet&)>)::{lambda(GeometrySet*)#1}>) const (parallel_for_each.h:51) ==178303== Other segment start (thread 1) ==178303== at 0x19FE087C: pthread_mutex_unlock (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_drd-amd64-linux.so) ==178303== by 0x3A2AD96: __gthread_mutex_unlock(pthread_mutex_t*) (gthr-default.h:779) ==178303== by 0x3A2ADED: std::mutex::unlock() (std_mutex.h:118) ==178303== by 0x3BEB896: std::lock_guard<std::mutex>::~lock_guard() (std_mutex.h:165) ==178303== by 0x408EA0E: BezierSpline::control_point_offsets() const (spline_bezier.cc:519) ==178303== by 0x408DD4D: BezierSpline::evaluated_points_size() const (spline_bezier.cc:395) ==178303== by 0x40B5217: blender::bke::spline_extrude_vert_size(Spline const&, Spline const&) (curve_to_mesh_convert.cc:250) ==178303== by 0x40B5690: blender::bke::calculate_result_offsets(blender::Span<std::unique_ptr<Spline, std::default_delete<Spline> > >, blender::Span<std::unique_ptr<Spline, std::default_delete<Spline> > >, bool) (curve_to_mesh_convert.cc:306) ==178303== by 0x40B7094: blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool) (curve_to_mesh_convert.cc:702) ==178303== by 0x496A2A4: blender::nodes::geometry_set_curve_to_mesh(GeometrySet&, GeometrySet const&, bool) (node_geo_curve_to_mesh.cc:52) ==178303== by 0x496A321: blender::nodes::geo_node_curve_to_mesh_exec(blender::nodes::GeoNodeExecParams)::{lambda(GeometrySet&)#1}::operator()(GeometrySet&) const (node_geo_curve_to_mesh.cc:67) ==178303== by 0x496A632: void blender::FunctionRef<void (GeometrySet&)>::callback_fn<blender::nodes::geo_node_curve_to_mesh_exec(blender::nodes::GeoNodeExecParams)::{lambda(GeometrySet&)#1}>(long, GeometrySet&) (BLI_function_ref.hh:107) ==178303== Other segment end (thread 1) ==178303== at 0x19FDF82C: pthread_mutex_lock (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_drd-amd64-linux.so) ==178303== by 0x3A2AD67: __gthread_mutex_lock(pthread_mutex_t*) (gthr-default.h:749) ==178303== by 0x3A2ADBB: std::mutex::lock() (std_mutex.h:100) ==178303== by 0x3BEB873: std::lock_guard<std::mutex>::lock_guard(std::mutex&) (std_mutex.h:159) ==178303== by 0x408CC0A: BezierSpline::ensure_auto_handles() const (spline_bezier.cc:224) ==178303== by 0x408F45C: BezierSpline::evaluated_positions() const (spline_bezier.cc:640) ==178303== by 0x40B4D0D: blender::bke::spline_extrude_to_mesh_data(blender::bke::ResultInfo const&, bool, blender::MutableSpan<MVert>, blender::MutableSpan<MEdge>, blender::MutableSpan<MLoop>, blender::MutableSpan<MPoly>) (curve_to_mesh_convert.cc:219) ==178303== by 0x40B6E03: blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const (curve_to_mesh_convert.cc:740) ==178303== by 0x40B9F62: void blender::threading::parallel_for<blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}>(blender::IndexRange, long, blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1} const&)::{lambda(tbb::blocked_range<long> const&)#1}::operator()(tbb::blocked_range<long>) const (BLI_task.hh:72) ==178303== by 0x40BF248: tbb::interface9::internal::start_for<tbb::blocked_range<long>, void blender::threading::parallel_for<blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}>(blender::IndexRange, long, blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1} const&)::{lambda(tbb::blocked_range<long> const&)#1}, tbb::auto_partitioner const>::run_body(tbb::blocked_range<long>&) (parallel_for.h:115) ==178303== by 0x40BEDC9: void tbb::interface9::internal::dynamic_grainsize_mode<tbb::interface9::internal::adaptive_mode<tbb::interface9::internal::auto_partition_type> >::work_balance<tbb::interface9::internal::start_for<tbb::blocked_range<long>, void blender::threading::parallel_for<blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}>(blender::IndexRange, long, blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1} const&)::{lambda(tbb::blocked_range<long> const&)#1}, tbb::auto_partitioner const>, tbb::blocked_range<long> >({lambda(blender::IndexRange)#1}&, tbb::blocked_range<long>&) (partitioner.h:423) ==178303== by 0x40BE9D1: void tbb::interface9::internal::partition_type_base<tbb::interface9::internal::auto_partition_type>::execute<tbb::interface9::internal::start_for<tbb::blocked_range<long>, void blender::threading::parallel_for<blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1}>(blender::IndexRange, long, blender::bke::curve_to_mesh_sweep(CurveEval const&, CurveEval const&, bool)::{lambda(blender::IndexRange)#1}::operator()(blender::IndexRange) const::{lambda(blender::IndexRange)#1} const&)::{lambda(tbb::blocked_range<long> const&)#1}, tbb::auto_partitioner const>, tbb::blocked_range<long> >({lambda(blender::IndexRange)#1}&, tbb::blocked_range<long>&) (partitioner.h:256) ==178303== ```
Member

Can check this in more detail tomorrow, but sounds very related to https://developer.blender.org/T91986

Can check this in more detail tomorrow, but sounds very related to https://developer.blender.org/T91986
Author
Member

Could be related / the same. Though I don't really see how that could lead to a race condition, I'll study the code of your patch there and test it here in drd. (will be tomorrow probably)

Could be related / the same. Though I don't really see how that could lead to a race condition, I'll study the code of your patch there and test it here in drd. (will be tomorrow probably)
Member

Ok, from what I can tell so far, the cycles update issue you found is the same as #91986. The threading bug seems to be a separate issue.

Ok, from what I can tell so far, the cycles update issue you found is the same as #91986. The threading bug seems to be a separate issue.
Author
Member

I'll look into it some more tonight or tomorrow. I would be very surprised if the threading issue was completely unrelated to the update issue as the race condition is on the generating of the normals of the curve object (paired with the syncing of those normals), and the normals are also what's wrong in the cycles sync. Also I get uninited values in thesyncing of the same normals sometimes, which could happen if the sync coincides with the allocating of the normal vectors.

But maybe the race condition just happens because the wrong data is synced ?

I'll look into it some more tonight or tomorrow. I would be very surprised if the threading issue was completely unrelated to the update issue as the race condition is on the generating of the normals of the curve object (paired with the syncing of those normals), and the normals are also what's wrong in the cycles sync. Also I get uninited values in thesyncing of the same normals *sometimes*, which could happen if the sync coincides with the allocating of the normal vectors. But maybe the race condition just happens because the wrong data is synced ?
Member

Well, certainly geometry nodes shouldn't be updating geometry at the same time as it is rendered.
The update issue is fixed by D13020 for me, but I'm still getting another crash in your file

Well, certainly geometry nodes shouldn't be updating geometry at the same time as it is rendered. The update issue is fixed by [D13020](https://archive.blender.org/developer/D13020) for me, but I'm still getting another crash in your file
Author
Member

Yes, I get that crash as well. And I suspect it is because of the threading issue. (Though that's just gut feeling and could be completely wrong)

Testing with valgrind/drd is rather a hassle though, so I'll have to do that later.

Yes, I get that crash as well. And I suspect it is because of the threading issue. (Though that's just gut feeling and could be completely wrong) Testing with valgrind/drd is rather a hassle though, so I'll have to do that later.
Member

I agree that it sounds related. And I hope #92649 might be related too, it would be nice if all this weirdness was the same thing.

I agree that it sounds related. And I hope #92649 might be related too, it would be nice if all this weirdness was the same thing.
Author
Member

In source/blender/blenkernel/intern/spline_bezier.cc:

Span<float3> BezierSpline::handle_positions_left() const
Span<float3> BezierSpline::handle_positions_right() const
  this->ensure_auto_handles(); is called, which recalculates the handles

However when constructing a bezier spline (for example from dna (source/blender/blenkernel/intern/curve_eval.cc, or maybe when copying) handle_positions_left/right is called to get a reference to the internal array to fill it. and at that point the handle positions are still uninited data. So calling ensure_auto_handles() recalculates stuff from uninited memory.

I'm not sure if this has any consequences though.

In source/blender/blenkernel/intern/spline_bezier.cc: ``` Span<float3> BezierSpline::handle_positions_left() const Span<float3> BezierSpline::handle_positions_right() const ``` ``` this->ensure_auto_handles(); is called, which recalculates the handles ``` However when constructing a bezier spline (for example from dna (source/blender/blenkernel/intern/curve_eval.cc, or maybe when copying) handle_positions_left/right is called to get a reference to the internal array to fill it. and at that point the handle positions are still uninited data. So calling ensure_auto_handles() recalculates stuff from uninited memory. I'm not sure if this has any consequences though.
Author
Member

Patching this up (sadly) doesn't fix the crash,

Patching this up (sadly) doesn't fix the crash,
Author
Member

I tried applying D13020 to D13083. But it still crashes if I quickly toggle the flip input for a while. It does seem to be harder to crash than without D32083.

I had high hopes for D32083 being the solution, for as far as I understand it it made sure the attributes (like the normals in my GN tree) got deep copied, and the crashes I saw looked like the renderthread accessing normals that were deleted from another thread. But that still happens.

I tried applying [D13020](https://archive.blender.org/developer/D13020) to [D13083](https://archive.blender.org/developer/D13083). But it still crashes if I quickly toggle the flip input for a while. It does seem to be harder to crash than without D32083. I had high hopes for D32083 being the solution, for as far as I understand it it made sure the attributes (like the normals in my GN tree) got deep copied, and the crashes I saw looked like the renderthread accessing normals that were deleted from another thread. But that still happens.

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Author
Member

In the current master ( f0bc7f3261 ) the syncing that was fixed with @D13020 is broken again.

It was broken by commit 1bc655c5aa Fix #92815: Incorrect handling of evaluated meshes from curves.

It seems even more broken now. Which does make it easier to reproduce, so maybe it's a win.

In the current master ( f0bc7f3261b823fe4efbe802ec6a2f3471bedd47 ) the syncing that was fixed with @[D13020](https://archive.blender.org/developer/D13020) is broken again. It was broken by commit 1bc655c5aa644c1b3b933f9e372ec5b5b504c0d5 Fix #92815: Incorrect handling of evaluated meshes from curves. It seems even more broken now. Which does make it easier to reproduce, so maybe it's a win.
Member

The "even more broken" bit will be fixed by D13135. That probably won't fix the other issue in this task which may be related to auto-smoothing.

The "even more broken" bit will be fixed by [D13135](https://archive.blender.org/developer/D13135). That probably won't fix the other issue in this task which may be related to auto-smoothing.
Author
Member

That's great.

Also: I can't get the current master to crash by mashing the checkbox , by the way. So maybe that automagically 'fixed' itself.

That's great. Also: I can't get the current master to crash by mashing the checkbox , by the way. So maybe that automagically 'fixed' itself.
Author
Member

I tested it quite thoroughly, and it looks like 1bc655c5aa fixed the crashing issue.

All the crashes happened in a mesh which looked mostly ok, but contained some invalid data. It looked to me as if the mesh data was accessed after it was freed and partially re-used. My theory was that mashing the checkbox very fast could trigger a rebuild of the evaluated mesh while it was still being synced to cycles.

As 1bc655c5 changes the way the evaluated mesh is passed to cycles I'm not really surprised it fixes (or maybe hides?) the crash.

I tested it quite thoroughly, and it looks like 1bc655c5aa644c1b3b933f9e372ec5b5b504c0d5 fixed the crashing issue. All the crashes happened in a mesh which looked mostly ok, but contained some invalid data. It looked to me as if the mesh data was accessed after it was freed and partially re-used. My theory was that mashing the checkbox very fast could trigger a rebuild of the evaluated mesh while it was still being synced to cycles. As 1bc655c5 changes the way the evaluated mesh is passed to cycles I'm not really surprised it fixes (or maybe hides?) the crash.
Member

That would be great. I'll test it myself once the fix for #92864 committed.

That would be great. I'll test it myself once the fix for #92864 committed.
Member

Changed status from 'Confirmed' to: 'Resolved'

Changed status from 'Confirmed' to: 'Resolved'
Hans Goudey self-assigned this 2021-11-11 20:46:34 +01:00
Member

Testing this bug, it seems to be resolved. If anyone can still reproduce it, we can reopen this report.

Testing this bug, it seems to be resolved. If anyone can still reproduce it, we can reopen this report.
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#92606
No description provided.