Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_subdiv_modifier.h12
-rw-r--r--source/blender/blenkernel/intern/subdiv_modifier.c71
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c2
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c14
4 files changed, 79 insertions, 20 deletions
diff --git a/source/blender/blenkernel/BKE_subdiv_modifier.h b/source/blender/blenkernel/BKE_subdiv_modifier.h
index 8a179206dd7..5447f9fda7c 100644
--- a/source/blender/blenkernel/BKE_subdiv_modifier.h
+++ b/source/blender/blenkernel/BKE_subdiv_modifier.h
@@ -40,18 +40,30 @@ void BKE_subsurf_modifier_subdiv_settings_init(struct SubdivSettings *settings,
const struct SubsurfModifierData *smd,
bool use_render_params);
+bool BKE_subsurf_modifier_use_custom_loop_normals(const struct SubsurfModifierData *smd,
+ const struct Mesh *mesh);
+
+/**
+ * Return true if GPU subdivision evaluation is disabled by force due to incompatible mesh or
+ * modifier settings. This will only return true if GPU subdivision is enabled in the preferences
+ * 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);
/**
* \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_ex(const struct Scene *scene,
const struct Object *ob,
+ const struct Mesh *mesh,
const struct SubsurfModifierData *smd,
int required_mode,
bool skip_check_is_last);
bool BKE_subsurf_modifier_can_do_gpu_subdiv(const struct Scene *scene,
const struct Object *ob,
+ const struct Mesh *mesh,
int required_mode);
extern void (*BKE_subsurf_modifier_free_gpu_cache_cb)(struct Subdiv *subdiv);
diff --git a/source/blender/blenkernel/intern/subdiv_modifier.c b/source/blender/blenkernel/intern/subdiv_modifier.c
index 525c4837bc4..df798ccd490 100644
--- a/source/blender/blenkernel/intern/subdiv_modifier.c
+++ b/source/blender/blenkernel/intern/subdiv_modifier.c
@@ -70,23 +70,20 @@ static ModifierData *modifier_get_last_enabled_for_mode(const Scene *scene,
return md;
}
-bool BKE_subsurf_modifier_can_do_gpu_subdiv_ex(const Scene *scene,
- const Object *ob,
- const SubsurfModifierData *smd,
- int required_mode,
- bool skip_check_is_last)
+bool BKE_subsurf_modifier_use_custom_loop_normals(const SubsurfModifierData *smd, const Mesh *mesh)
{
- if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) {
- return false;
- }
+ return (smd->flags & eSubsurfModifierFlag_UseCustomNormals) && (mesh->flag & ME_AUTOSMOOTH) &&
+ CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
+}
- if (!skip_check_is_last) {
- ModifierData *md = modifier_get_last_enabled_for_mode(scene, ob, required_mode);
- if (md != (const ModifierData *)smd) {
- return false;
- }
- }
+bool subsurf_modifier_use_autosmooth_or_split_normals(const SubsurfModifierData *smd,
+ const Mesh *mesh)
+{
+ return (mesh->flag & ME_AUTOSMOOTH) || BKE_subsurf_modifier_use_custom_loop_normals(smd, mesh);
+}
+static bool is_subdivision_evaluation_possible_on_gpu(void)
+{
/* Only OpenGL is supported for OpenSubdiv evaluation for now. */
if (GPU_backend_get_type() != GPU_BACKEND_OPENGL) {
return false;
@@ -104,8 +101,52 @@ bool BKE_subsurf_modifier_can_do_gpu_subdiv_ex(const Scene *scene,
return true;
}
+bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const SubsurfModifierData *smd,
+ const Mesh *mesh)
+{
+ if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) {
+ /* GPU subdivision is explicitely disabled, so we don't force it. */
+ return false;
+ }
+
+ if (!is_subdivision_evaluation_possible_on_gpu()) {
+ /* The GPU type is not compatible with the subdivision. */
+ return false;
+ }
+
+ return subsurf_modifier_use_autosmooth_or_split_normals(smd, mesh);
+}
+
+bool BKE_subsurf_modifier_can_do_gpu_subdiv_ex(const Scene *scene,
+ const Object *ob,
+ const Mesh *mesh,
+ const SubsurfModifierData *smd,
+ int required_mode,
+ bool skip_check_is_last)
+{
+ if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) {
+ return false;
+ }
+
+ /* Deactivate GPU subdivision if autosmooth or custom split normals are used as those are
+ * complicated to support on GPU, and should really be separate workflows. */
+ if (subsurf_modifier_use_autosmooth_or_split_normals(smd, mesh)) {
+ return false;
+ }
+
+ if (!skip_check_is_last) {
+ ModifierData *md = modifier_get_last_enabled_for_mode(scene, ob, required_mode);
+ if (md != (const ModifierData *)smd) {
+ return false;
+ }
+ }
+
+ return is_subdivision_evaluation_possible_on_gpu();
+}
+
bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Scene *scene,
const Object *ob,
+ const Mesh *mesh,
int required_mode)
{
ModifierData *md = modifier_get_last_enabled_for_mode(scene, ob, required_mode);
@@ -119,7 +160,7 @@ bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Scene *scene,
}
return BKE_subsurf_modifier_can_do_gpu_subdiv_ex(
- scene, ob, (SubsurfModifierData *)md, required_mode, true);
+ scene, ob, mesh, (SubsurfModifierData *)md, required_mode, true);
}
void (*BKE_subsurf_modifier_free_gpu_cache_cb)(Subdiv *subdiv) = NULL;
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index db4c95baedb..71f13fe9423 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1726,7 +1726,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
const int required_mode = BKE_subsurf_modifier_eval_required_mode(DRW_state_is_scene_render(),
is_editmode);
- const bool do_subdivision = BKE_subsurf_modifier_can_do_gpu_subdiv(scene, ob, required_mode);
+ const bool do_subdivision = BKE_subsurf_modifier_can_do_gpu_subdiv(scene, ob, me, required_mode);
MeshBufferList *mbuflist = &cache->final.buff;
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index a8c6687193b..2006ca1b1b7 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -250,7 +250,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
* assigned at this stage of modifier stack evaluation. */
const bool is_editmode = (mesh->edit_mesh != NULL);
const int required_mode = BKE_subsurf_modifier_eval_required_mode(is_render_mode, is_editmode);
- if (BKE_subsurf_modifier_can_do_gpu_subdiv_ex(scene, ctx->object, smd, required_mode, false)) {
+ if (BKE_subsurf_modifier_can_do_gpu_subdiv_ex(
+ scene, ctx->object, mesh, smd, required_mode, false)) {
subdiv_cache_cpu_evaluation_settings(ctx, mesh, smd);
return result;
}
@@ -262,9 +263,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Happens on bad topology, but also on empty input mesh. */
return result;
}
- const bool use_clnors = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) &&
- (mesh->flag & ME_AUTOSMOOTH) &&
- CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
+ const bool use_clnors = BKE_subsurf_modifier_use_custom_loop_normals(smd, mesh);
if (use_clnors) {
/* If custom normals are present and the option is turned on calculate the split
* normals and clear flag so the normals get interpolated to the result mesh. */
@@ -428,6 +427,13 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(layout, ptr, "show_only_control_edges", 0, NULL, ICON_NONE);
+ SubsurfModifierData *smd = ptr->data;
+ Object *ob = ob_ptr.data;
+ Mesh *mesh = 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);
+ }
+
modifier_panel_end(layout, ptr);
}