OpenSubdiv: Resolve crashes when other object depends on subsurf-ed object
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 3 Aug 2015 13:57:22 +0000 (15:57 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 3 Aug 2015 13:57:22 +0000 (15:57 +0200)
Cases like using subsurfed object as a boolean operand can't be evaluated
on GPU and needs to have all the CCG on CPU.

This commit resolves existing configuration to survive, but new configurations
would need to have some sort of forced object update so all the data is being
moved on CPU if it was previously on GPU.

source/blender/blenkernel/BKE_depsgraph.h
source/blender/blenkernel/intern/depsgraph.c
source/blender/depsgraph/CMakeLists.txt
source/blender/depsgraph/SConscript
source/blender/depsgraph/intern/depsgraph.cc
source/blender/modifiers/intern/MOD_subsurf.c

index 862f91f567e6f413889d33fa5ea6b7529ec5c2e8..7d7db332dd2070e7c5c7085f85bf0c29924caedd 100644 (file)
@@ -72,6 +72,10 @@ enum {
         * who're using curve deform, where_on_path and so.
         */
        DAG_EVAL_NEED_CURVE_PATH = 1,
+       /* Scene evaluation would need to have object's data on CPU,
+        * meaning no GPU shortcuts is allowed.
+        */
+       DAG_EVAL_NEED_CPU        = 2,
 };
 
 /* Global initialization/deinitialization */
index 2fd53045e2930e19a1d9266a75be9d4ddee157b4..b7ad43869b7eaa66ef7f9d5dc8882e40766864a4 100644 (file)
@@ -1138,6 +1138,13 @@ void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel
        /* parent relation is for cycle checking */
        dag_add_parent_relation(forest, fob1, fob2, rel, name);
 
+       /* TODO(sergey): Find a better place for this. */
+#ifdef WITH_OPENSUBDIV
+       if ((rel & DAG_RL_DATA_DATA) != 0) {
+               fob1->eval_flags |= DAG_EVAL_NEED_CPU;
+       }
+#endif
+
        while (itA) { /* search if relation exist already */
                if (itA->node == fob2) {
                        itA->type |= rel;
index dcdb14d0ba0c8d923be6aa4b4848067d484c2946..f3ff709e98b1703295f5f69fd503f5fd07cb2257 100644 (file)
@@ -115,4 +115,8 @@ if(WITH_BOOST)
        add_definitions(-DHAVE_BOOST_FUNCTION_BINDINGS)
 endif()
 
+if(WITH_OPENSUBDIV)
+       add_definitions(-DWITH_OPENSUBDIV)
+endif()
+
 blender_add_lib(bf_depsgraph "${SRC}" "${INC}" "${INC_SYS}")
index dd0552e19a21728ac256f1d2acf45402266b099a..7f49e8f464301ee6eb8fe844c1b033bec10add0a 100644 (file)
@@ -69,6 +69,9 @@ else:
 if env['WITH_BF_LEGACY_DEPSGRAPH']:
     defs.append('WITH_LEGACY_DEPSGRAPH')
 
+if env['WITH_BF_OPENSUBDIV']:
+    defs.append('WITH_OPENSUBDIV')
+
 env.BlenderLib(libname='bf_depsgraph', sources=sources,
                includes=incs, defines=defs,
                libtype=['core', 'player'], priority=[200, 40])
index e9b2a06cf7b1f67737b3275939b9fae2231f0fa6..94c01f362be3ea833fad000d4ad7868bfc9a5910 100644 (file)
@@ -44,6 +44,8 @@ extern "C" {
 #include "DNA_object_types.h"
 #include "DNA_sequence_types.h"
 
+#include "BKE_depsgraph.h"
+
 #include "RNA_access.h"
 }
 
@@ -351,6 +353,13 @@ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
 {
        /* Create new relation, and add it to the graph. */
        DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, type, description);
+       /* TODO(sergey): Find a better place for this. */
+#ifdef WITH_OPENSUBDIV
+       if (type == DEPSREL_TYPE_GEOMETRY_EVAL) {
+               IDDepsNode *id_to = to->owner->owner;
+               id_to->eval_flags |= DAG_EVAL_NEED_CPU;
+       }
+#endif
        return rel;
 }
 
index 5a03da91b2d60480ca4907740926ad1418a279ee..ff778e62507448d6576fd8ab2761b7c61ce419c1 100644 (file)
@@ -42,6 +42,7 @@
 
 
 #include "BKE_cdderivedmesh.h"
+#include "BKE_depsgraph.h"
 #include "BKE_scene.h"
 #include "BKE_subsurf.h"
 
@@ -120,7 +121,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
         * could be disabled.
         */
        if (md->next == NULL && allow_gpu && do_cddm_convert == false) {
-               subsurf_flags |= SUBSURF_USE_GPU_BACKEND;
+               if ((DAG_get_eval_flags_for_object(md->scene, ob) & DAG_EVAL_NEED_CPU) == 0) {
+                       subsurf_flags |= SUBSURF_USE_GPU_BACKEND;
+               }
        }
 #endif