diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h index dd01c4ffd07..c99f311fbca 100644 --- a/source/blender/blenkernel/BKE_subdiv_modifier.h +++ b/source/blender/blenkernel/BKE_subdiv_modifier.h @@ -19,6 +19,7 @@ extern "C" { * programmatic way of detecting this. */ #define MAX_GPU_SUBDIV_SSBOS 12 +struct Depsgraph; struct Mesh; struct Object; struct Scene; @@ -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 504dc8e5b29..9e6ffcee336 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.cc +++ b/source/blender/blenkernel/intern/subdiv_modifier.cc @@ -15,6 +15,8 @@ #include "BKE_modifier.h" #include "BKE_subdiv.h" +#include "DEG_depsgraph_query.h" + #include "GPU_capabilities.h" #include "GPU_context.h" @@ -112,8 +114,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 and paint mode UI requires the mesh - see sculpt_update_object. */ + if ((ob->mode & OB_MODE_ALL_SCULPT) && DEG_is_active(depsgraph)) { + return true; + } + + /* Some dependencies request it through depsgraph. */ + if (DEG_get_eval_flags_for_id(depsgraph, &ob->id) & DAG_EVAL_NEED_CPU_EVALUATED_MESH) { + 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 +144,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 +164,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..aa42f580fbd 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_EVALUATED_MESH = (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 31023b8ca4a..f3f437bbcf0 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1312,6 +1312,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_EVALUATED_MESH); } else if (con->type == CONSTRAINT_TYPE_SHRINKWRAP) { bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *)con->data; @@ -1319,6 +1320,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_EVALUATED_MESH); /* Add dependency on normal layers if necessary. */ if (ct->tar->type == OB_MESH && scon->shrinkType != MOD_SHRINKWRAP_NEAREST_VERTEX) { @@ -2019,10 +2021,13 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) add_relation(object_transform_simulation_init_key, rb_simulate_key, "Object Transform -> Rigidbody Sim Eval"); + /* Geometry must be known to create the rigid body. RBO_MESH_BASE * uses the non-evaluated mesh, so then the evaluation is * unnecessary. */ - if (rigidbody_object_depends_on_evaluated_geometry(object->rigidbody_object)) { + eRigidBody_MeshSource mesh_source = rigidbody_object_depends_on_evaluated_geometry( + object->rigidbody_object); + if (mesh_source != RBO_MESH_BASE) { /* NOTE: We prefer this relation to be never killed, to avoid * access partially evaluated mesh from solver. */ ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY); @@ -2030,6 +2035,10 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) rb_simulate_key, "Object Geom Eval -> Rigidbody Sim Eval", RELATION_FLAG_GODMODE); + /* Request the CPU mesh when necessary. */ + if (mesh_source == RBO_MESH_FINAL) { + add_special_eval_flag(&object->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); + } } /* Final transform is whatever the solver gave to us. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h index 76066ce97a7..bb83be9d3cf 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_impl.h @@ -105,17 +105,16 @@ Relation *DepsgraphRelationBuilder::add_node_handle_relation(const KeyType &key_ return nullptr; } -static inline bool rigidbody_object_depends_on_evaluated_geometry(const RigidBodyOb *rbo) +static inline eRigidBody_MeshSource rigidbody_object_depends_on_evaluated_geometry( + const RigidBodyOb *rbo) { if (rbo == nullptr) { - return false; + return RBO_MESH_BASE; } if (ELEM(rbo->shape, RB_SHAPE_CONVEXH, RB_SHAPE_TRIMESH)) { - if (rbo->mesh_source != RBO_MESH_BASE) { - return true; - } + return static_cast(rbo->mesh_source); } - return false; + return RBO_MESH_BASE; } template 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/depsgraph/intern/depsgraph_physics.cc b/source/blender/depsgraph/intern/depsgraph_physics.cc index d7d03ec3261..4f8d57153f9 100644 --- a/source/blender/depsgraph/intern/depsgraph_physics.cc +++ b/source/blender/depsgraph/intern/depsgraph_physics.cc @@ -140,6 +140,10 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle, DEG_add_object_pointcache_relation(handle, relation->ob, DEG_OB_COMP_GEOMETRY, name); } + if (ELEM(relation->pd->shape, PFIELD_SHAPE_POINTS)) { + DEG_add_special_eval_flag(handle, &relation->ob->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); + } + /* Smoke flow relations. */ if (relation->pd->forcefield == PFIELD_FLUIDFLOW && relation->pd->f_source != nullptr) { DEG_add_object_pointcache_relation( diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c index c4ac6f680e6..10ca76ef9d7 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_EVALUATED_MESH); 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_EVALUATED_MESH); 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 458983c0ca5..1f57b7ea703 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -82,10 +82,12 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte if (amd->start_cap != nullptr) { DEG_add_object_relation( ctx->node, amd->start_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier Start Cap"); + DEG_add_special_eval_flag(ctx->node, &amd->start_cap->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } if (amd->end_cap != nullptr) { DEG_add_object_relation( ctx->node, amd->end_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier End Cap"); + DEG_add_special_eval_flag(ctx->node, &amd->end_cap->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } if (amd->curve_ob) { DEG_add_object_relation( diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index 6bc7c045de6..9aa69c9cd60 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -108,12 +108,15 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object != nullptr) { DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_TRANSFORM, "Boolean Modifier"); DEG_add_object_relation(ctx->node, bmd->object, DEG_OB_COMP_GEOMETRY, "Boolean Modifier"); + DEG_add_special_eval_flag(ctx->node, &bmd->object->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } Collection *col = bmd->collection; if ((bmd->flag & eBooleanModifierFlag_Collection) && col != nullptr) { DEG_add_collection_geometry_relation(ctx->node, col, "Boolean Modifier"); + DEG_add_collection_geometry_special_eval_flag( + ctx->node, col, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } /* We need own transformation as well. */ DEG_add_depends_on_transform_relation(ctx->node, "Boolean Modifier"); diff --git a/source/blender/modifiers/intern/MOD_datatransfer.cc b/source/blender/modifiers/intern/MOD_datatransfer.cc index fbce7ef6da9..4ae421f0d07 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.cc +++ b/source/blender/modifiers/intern/MOD_datatransfer.cc @@ -124,6 +124,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte DEG_add_object_relation( ctx->node, dtmd->ob_source, DEG_OB_COMP_GEOMETRY, "DataTransfer Modifier"); DEG_add_customdata_mask(ctx->node, dtmd->ob_source, &cddata_masks); + DEG_add_special_eval_flag(ctx->node, &dtmd->ob_source->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); if (dtmd->flags & MOD_DATATRANSFER_OBSRC_TRANSFORM) { DEG_add_object_relation( diff --git a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc index cb13f032969..bd54d2182be 100644 --- a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc +++ b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc @@ -66,6 +66,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte ctx->node, mvmd->object, DEG_OB_COMP_GEOMETRY, "Mesh to Volume Modifier"); DEG_add_object_relation( ctx->node, mvmd->object, DEG_OB_COMP_TRANSFORM, "Mesh to Volume Modifier"); + DEG_add_special_eval_flag(ctx->node, &mvmd->object->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } } diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 8cadc31b9c2..495d65f664c 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -156,6 +156,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte if (mmd->object != NULL) { DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_TRANSFORM, "Mesh Deform Modifier"); DEG_add_object_relation(ctx->node, mmd->object, DEG_OB_COMP_GEOMETRY, "Mesh Deform Modifier"); + DEG_add_special_eval_flag(ctx->node, &mmd->object->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } /* We need own transformation as well. */ DEG_add_depends_on_transform_relation(ctx->node, "Mesh Deform Modifier"); diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 564c270674b..399d3acb4c4 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -261,6 +261,8 @@ static void add_collection_relation(const ModifierUpdateDepsgraphContext *ctx, { DEG_add_collection_geometry_relation(ctx->node, &collection, "Nodes Modifier"); DEG_add_collection_geometry_customdata_mask(ctx->node, &collection, &dependency_data_mask); + DEG_add_collection_geometry_special_eval_flag( + ctx->node, &collection, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } static void add_object_relation(const ModifierUpdateDepsgraphContext *ctx, Object &object) @@ -273,6 +275,7 @@ static void add_object_relation(const ModifierUpdateDepsgraphContext *ctx, Objec else if (DEG_object_has_geometry_component(&object)) { DEG_add_object_relation(ctx->node, &object, DEG_OB_COMP_GEOMETRY, "Nodes Modifier"); DEG_add_customdata_mask(ctx->node, &object, &dependency_data_mask); + DEG_add_special_eval_flag(ctx->node, &object.id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } } } diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index 49944a14e28..b1c805fe623 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -163,6 +163,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier"); DEG_add_object_relation(ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier"); DEG_add_customdata_mask(ctx->node, smd->target, &mask); + DEG_add_special_eval_flag(ctx->node, &smd->target->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) { DEG_add_special_eval_flag(ctx->node, &smd->target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY); } @@ -173,6 +174,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte DEG_add_object_relation( ctx->node, smd->auxTarget, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier"); DEG_add_customdata_mask(ctx->node, smd->auxTarget, &mask); + DEG_add_special_eval_flag(ctx->node, &smd->auxTarget->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); if (smd->shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) { DEG_add_special_eval_flag(ctx->node, &smd->auxTarget->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY); } diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index 6619523bee6..4a4f35632fd 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.cc +++ b/source/blender/modifiers/intern/MOD_subsurf.cc @@ -242,14 +242,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Delay evaluation to the draw code if possible, provided we do not have to apply the modifier. */ if ((ctx->flag & MOD_APPLY_TO_BASE_MESH) == 0) { - Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); const bool is_render_mode = (ctx->flag & MOD_APPLY_RENDER) != 0; /* Same check as in `DRW_mesh_batch_cache_create_requested` to keep both code coherent. The * difference is that here we do not check for the final edit mesh pointer as it is not yet * assigned at this stage of modifier stack evaluation. */ const bool is_editmode = (mesh->edit_mesh != nullptr); const int required_mode = BKE_subsurf_modifier_eval_required_mode(is_render_mode, is_editmode); - if (BKE_subsurf_modifier_can_do_gpu_subdiv(scene, ctx->object, mesh, smd, required_mode)) { + if (BKE_subsurf_modifier_can_do_gpu_subdiv( + ctx->depsgraph, ctx->object, mesh, smd, required_mode)) { subdiv_cache_mesh_wrapper_settings(ctx, mesh, smd, runtime_data); return result; } @@ -425,8 +425,10 @@ static void panel_draw(const bContext *C, Panel *panel) SubsurfModifierData *smd = static_cast(ptr->data); Object *ob = static_cast(ob_ptr.data); const Mesh *mesh = static_cast(ob->data); - if (BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(smd, mesh)) { - uiItemL(layout, "Autosmooth or custom normals detected, disabling GPU subdivision", ICON_INFO); + if (BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(depsgraph, ob, mesh, smd)) { + uiItemL(layout, + "Disabling GPU subdivision due to autosmooth, custom normals or dependencies", + ICON_INFO); } else if (Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob)) { if (ModifierData *md_eval = BKE_modifiers_findby_name(ob_eval, smd->modifier.name)) { diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.cc b/source/blender/modifiers/intern/MOD_surfacedeform.cc index d13a15e724b..d3d692bb226 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.cc +++ b/source/blender/modifiers/intern/MOD_surfacedeform.cc @@ -274,6 +274,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte if (smd->target != nullptr) { DEG_add_object_relation( ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Surface Deform Modifier"); + DEG_add_special_eval_flag(ctx->node, &smd->target->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } } diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.cc b/source/blender/modifiers/intern/MOD_weightvgproximity.cc index 3ebdb24e853..e5e82ace8f5 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.cc +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.cc @@ -381,6 +381,8 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte wmd->proximity_mode == MOD_WVG_PROXIMITY_GEOMETRY) { DEG_add_object_relation( ctx->node, wmd->proximity_ob_target, DEG_OB_COMP_GEOMETRY, "WeightVGProximity Modifier"); + DEG_add_special_eval_flag( + ctx->node, &wmd->proximity_ob_target->id, DAG_EVAL_NEED_CPU_EVALUATED_MESH); } need_transform_relation = true; }