[Bf-blender-cvs] [5bdc02f4446] temp-angavrilov: Subdivision Surface: add dependency graph tracking when cpu mesh is needed.

Alexander Gavrilov noreply at git.blender.org
Sat Feb 4 21:41:02 CET 2023


Commit: 5bdc02f4446d5ccd2e212b09fa61b77bbb3d8ae9
Author: Alexander Gavrilov
Date:   Wed Jan 25 11:37:40 2023 +0200
Branches: temp-angavrilov
https://developer.blender.org/rB5bdc02f4446d5ccd2e212b09fa61b77bbb3d8ae9

Subdivision Surface: add dependency graph tracking when cpu mesh is needed.

Constraints targeting mesh vertex groups, as well as likely modifiers
now tag their targets with a dependency graph flag to notify that the
fully evaluated mesh is needed on the CPU. This is used to disable GPU
subdiv in those cases.

In addition, the evaluated mesh is used by sculpt and paint modes.

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

M	source/blender/blenkernel/BKE_subdiv_modifier.h
M	source/blender/blenkernel/intern/subdiv_modifier.cc
M	source/blender/depsgraph/DEG_depsgraph.h
M	source/blender/depsgraph/DEG_depsgraph_build.h
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
M	source/blender/depsgraph/intern/depsgraph_build.cc
M	source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c
M	source/blender/modifiers/intern/MOD_array.cc
M	source/blender/modifiers/intern/MOD_boolean.cc
M	source/blender/modifiers/intern/MOD_datatransfer.cc
M	source/blender/modifiers/intern/MOD_mesh_to_volume.cc
M	source/blender/modifiers/intern/MOD_meshdeform.c
M	source/blender/modifiers/intern/MOD_shrinkwrap.c
M	source/blender/modifiers/intern/MOD_subsurf.cc
M	source/blender/modifiers/intern/MOD_surfacedeform.cc
M	source/blender/modifiers/intern/MOD_weightvgproximity.cc

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

diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h
index dd01c4ffd07..f20e2028b37 100644
--- a/source/blender/blenkernel/BKE_subdiv_modifier.h
+++ b/source/blender/blenkernel/BKE_subdiv_modifier.h
@@ -7,6 +7,7 @@
 
 #pragma once
 
+#include "BKE_DerivedMesh.h"
 #include "BKE_subdiv.h"
 
 #include "BLI_sys_types.h"
@@ -68,12 +69,15 @@ bool BKE_subsurf_modifier_use_custom_loop_normals(const struct SubsurfModifierDa
  * and supported by the GPU. It is mainly useful for showing UI messages.
  */
 bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(
-    const struct SubsurfModifierData *smd, const struct Mesh *mesh);
+    const struct Depsgraph *depsgraph,
+    const struct Object *ob,
+    const struct Mesh *mesh,
+    const struct SubsurfModifierData *smd);
 /**
  * \param skip_check_is_last: When true, we assume that the modifier passed is the last enabled
  * modifier in the stack.
  */
-bool BKE_subsurf_modifier_can_do_gpu_subdiv(const struct Scene *scene,
+bool BKE_subsurf_modifier_can_do_gpu_subdiv(const struct Depsgraph *depsgraph,
                                             const struct Object *ob,
                                             const struct Mesh *mesh,
                                             const struct SubsurfModifierData *smd,
diff --git a/source/blender/blenkernel/intern/subdiv_modifier.cc b/source/blender/blenkernel/intern/subdiv_modifier.cc
index 60d55af215c..eb69f8bb5c9 100644
--- a/source/blender/blenkernel/intern/subdiv_modifier.cc
+++ b/source/blender/blenkernel/intern/subdiv_modifier.cc
@@ -14,6 +14,7 @@
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_subdiv.h"
+#include "DEG_depsgraph_query.h"
 
 #include "GPU_capabilities.h"
 #include "GPU_context.h"
@@ -112,8 +113,25 @@ static bool is_subdivision_evaluation_possible_on_gpu()
   return true;
 }
 
-bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const SubsurfModifierData *smd,
-                                                                const Mesh *mesh)
+static bool subsurf_modifier_has_cpu_dependents(const Depsgraph *depsgraph, const Object *ob)
+{
+  /* The sculpt mode UI requires the mesh. */
+  if (ob->mode & OB_MODE_ALL_SCULPT) {
+    return true;
+  }
+
+  /* Some dependencies request it through depsgraph. */
+  if (DEG_get_eval_flags_for_id(depsgraph, &ob->id) & DAG_EVAL_NEED_CPU_SUBSURF) {
+    return true;
+  }
+
+  return false;
+}
+
+bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const Depsgraph *depsgraph,
+                                                                const Object *ob,
+                                                                const Mesh *mesh,
+                                                                const SubsurfModifierData *smd)
 {
   if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) {
     /* GPU subdivision is explicitly disabled, so we don't force it. */
@@ -125,10 +143,11 @@ bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const SubsurfMod
     return false;
   }
 
-  return subsurf_modifier_use_autosmooth_or_split_normals(smd, mesh);
+  return subsurf_modifier_use_autosmooth_or_split_normals(smd, mesh) ||
+         subsurf_modifier_has_cpu_dependents(depsgraph, ob);
 }
 
-bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Scene *scene,
+bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Depsgraph *depsgraph,
                                             const Object *ob,
                                             const Mesh *mesh,
                                             const SubsurfModifierData *smd,
@@ -144,6 +163,12 @@ bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Scene *scene,
     return false;
   }
 
+  /* Deactivate if some other dependencies need a final CPU mesh. */
+  if (subsurf_modifier_has_cpu_dependents(depsgraph, ob)) {
+    return false;
+  }
+
+  const Scene *scene = DEG_get_evaluated_scene(depsgraph);
   ModifierData *md = modifier_get_last_enabled_for_mode(scene, ob, required_mode);
   if (md != (const ModifierData *)smd) {
     return false;
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index 48a6a5cda74..e705f0f6371 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -55,6 +55,8 @@ enum {
   /* A shrinkwrap modifier or constraint targeting this mesh needs information
    * about non-manifold boundary edges for the Target Normal Project mode. */
   DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY = (1 << 1),
+  /* A modifier or constraints needs fully subdivided mesh on the CPU. */
+  DAG_EVAL_NEED_CPU_SUBSURF = (1 << 2),
 };
 
 #ifdef __cplusplus
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h
index ffeb5e897ab..022efc5ee2b 100644
--- a/source/blender/depsgraph/DEG_depsgraph_build.h
+++ b/source/blender/depsgraph/DEG_depsgraph_build.h
@@ -134,6 +134,9 @@ void DEG_add_collection_geometry_relation(struct DepsNodeHandle *node_handle,
 void DEG_add_collection_geometry_customdata_mask(struct DepsNodeHandle *node_handle,
                                                  struct Collection *collection,
                                                  const struct CustomData_MeshMasks *masks);
+void DEG_add_collection_geometry_special_eval_flag(struct DepsNodeHandle *node_handle,
+                                                   struct Collection *collection,
+                                                   uint32_t flag);
 void DEG_add_simulation_relation(struct DepsNodeHandle *node_handle,
                                  struct Simulation *simulation,
                                  const char *description);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index b8581b16aef..203861b7d97 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -1306,6 +1306,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
           add_relation(target_transform_key, constraint_op_key, cti->name);
           add_relation(target_geometry_key, constraint_op_key, cti->name);
           add_customdata_mask(ct->tar, DEGCustomDataMeshMasks::MaskVert(CD_MASK_MDEFORMVERT));
+          add_special_eval_flag(&ct->tar->id, DAG_EVAL_NEED_CPU_SUBSURF);
         }
         else if (con->type == CONSTRAINT_TYPE_SHRINKWRAP) {
           bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *)con->data;
@@ -1313,6 +1314,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
           /* Constraints which requires the target object surface. */
           ComponentKey target_key(&ct->tar->id, NodeType::GEOMETRY);
           add_relation(target_key, constraint_op_key, cti->name);
+          add_special_eval_flag(&ct->tar->id, DAG_EVAL_NEED_CPU_SUBSURF);
 
           /* Add dependency on normal layers if necessary. */
           if (ct->tar->type == OB_MESH && scon->shrinkType != MOD_SHRINKWRAP_NEAREST_VERTEX) {
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index 9eeb074bbaa..5569cf49acf 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -122,6 +122,19 @@ void DEG_add_collection_geometry_customdata_mask(DepsNodeHandle *node_handle,
   FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
 }
 
+void DEG_add_collection_geometry_special_eval_flag(struct DepsNodeHandle *node_handle,
+                                                   struct Collection *collection,
+                                                   uint32_t flag)
+{
+  FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, ob) {
+    DEG_add_special_eval_flag(node_handle, &ob->id, flag);
+    if (ob->type == OB_EMPTY && ob->instance_collection != nullptr) {
+      DEG_add_collection_geometry_special_eval_flag(node_handle, ob->instance_collection, flag);
+    }
+  }
+  FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+}
+
 void DEG_add_simulation_relation(DepsNodeHandle *node_handle,
                                  Simulation *simulation,
                                  const char *description)
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c
index ae0eb5a0a25..fe3b3281f06 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c
@@ -209,6 +209,7 @@ static void updateDepsgraph(GpencilModifierData *md,
     DEG_add_object_relation(ctx->node, mmd->target, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
     DEG_add_object_relation(ctx->node, mmd->target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
     DEG_add_customdata_mask(ctx->node, mmd->target, &mask);
+    DEG_add_special_eval_flag(ctx->node, &mmd->target->id, DAG_EVAL_NEED_CPU_SUBSURF);
     if (mmd->shrink_type == MOD_SHRINKWRAP_TARGET_PROJECT) {
       DEG_add_special_eval_flag(ctx->node, &mmd->target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
     }
@@ -219,6 +220,7 @@ static void updateDepsgraph(GpencilModifierData *md,
     DEG_add_object_relation(
         ctx->node, mmd->aux_target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
     DEG_add_customdata_mask(ctx->node, mmd->aux_target, &mask);
+    DEG_add_special_eval_flag(ctx->node, &mmd->aux_target->id, DAG_EVAL_NEED_CPU_SUBSURF);
     if (mmd->shrink_type == MOD_SHRINKWRAP_TARGET_PROJECT) {
       DEG_add_special_eval_flag(
           ctx->node, &mmd->aux_target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc
index 512ef154516..c8ea3ba5438 100644
--- a/source/blender/modifiers/intern/MOD_array.cc
+++ b/source/blender/modifiers/intern/MOD_array.cc
@@ -76,10 +76,12 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
   if (amd->start_cap != nullptr) {
     DEG_add_object_relation(
         ctx->node, amd

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list