Blender V5.0
subdiv_modifier.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include "MEM_guardedalloc.h"
8
9#include "DNA_mesh_types.h"
10#include "DNA_modifier_types.h"
11#include "DNA_object_types.h"
12#include "DNA_userdef_types.h"
13
14#include "BKE_attribute.hh"
15#include "BKE_mesh.hh"
16#include "BKE_modifier.hh"
17#include "BKE_subdiv.hh"
18
19#include "GPU_capabilities.hh"
20#include "GPU_context.hh"
21
22using namespace blender::bke;
23
25 const bool use_render_params)
26{
27 const int requested_levels = (use_render_params) ? smd->renderLevels : smd->levels;
28
29 subdiv::Settings settings{};
30 settings.is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE);
32 settings.level = settings.is_simple ? 1 :
33 (settings.is_adaptive ? smd->quality : requested_levels);
36 smd->boundary_smooth);
38
39 return settings;
40}
41
42bool BKE_subsurf_modifier_runtime_init(SubsurfModifierData *smd, const bool use_render_params)
43{
44 subdiv::Settings settings = BKE_subsurf_modifier_settings_init(smd, use_render_params);
45
47 if (settings.level == 0) {
48 /* Modifier is effectively disabled, but still update settings if runtime data
49 * was already allocated. */
50 if (runtime_data) {
51 runtime_data->settings = settings;
52
53 runtime_data->used_cpu = runtime_data->used_gpu = 0;
54 }
55
56 return false;
57 }
58
59 /* Allocate runtime data if it did not exist yet. */
60 if (runtime_data == nullptr) {
61 runtime_data = MEM_callocN<SubsurfRuntimeData>(__func__);
62 smd->modifier.runtime = runtime_data;
63 }
64 runtime_data->settings = settings;
65 return true;
66}
67
69{
71 return false;
72 }
73 const std::optional<AttributeMetaData> meta_data = mesh->attributes().lookup_meta_data(
74 "custom_normal");
75 return meta_data && meta_data->domain == AttrDomain::Corner &&
76 meta_data->data_type == AttrType::Int16_2D;
77}
78
84
86{
88 return false;
89 }
90
92 return false;
93 }
94
95 return true;
96}
97
99 const Mesh *mesh)
100{
101 if ((U.gpu_flag & USER_GPU_FLAG_SUBDIVISION_EVALUATION) == 0) {
102 /* GPU subdivision is explicitly disabled, so we don't force it. */
103 return false;
104 }
105
107 /* The GPU type is not compatible with the subdivision. */
108 return false;
109 }
110
111 /* Deactivate GPU subdivision if sharp edges or custom normals are used as those are
112 * complicated to support on GPU, and should really be separate workflows. */
114}
115
122
124
126 const Mesh *mesh,
127 const bool for_draw_code)
128{
129 if (for_draw_code) {
130 runtime_data->used_gpu = 2; /* countdown in frames */
131
132 return runtime_data->subdiv_gpu = subdiv::update_from_mesh(
133 runtime_data->subdiv_gpu, &runtime_data->settings, mesh);
134 }
135 runtime_data->used_cpu = 2;
136 return runtime_data->subdiv_cpu = subdiv::update_from_mesh(
137 runtime_data->subdiv_cpu, &runtime_data->settings, mesh);
138}
139
140int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode)
141{
142 if (is_final_render) {
144 }
145
146 return eModifierMode_Realtime | (is_edit_mode ? int(eModifierMode_Editmode) : 0);
147}
#define MAX_GPU_SUBDIV_SSBOS
void(* BKE_subsurf_modifier_free_gpu_cache_cb)(blender::bke::subdiv::Subdiv *subdiv)
@ eModifierMode_Render
@ eModifierMode_Editmode
@ eModifierMode_Realtime
@ SUBSURF_TYPE_SIMPLE
@ eSubsurfModifierFlag_UseRecursiveSubdivision
@ eSubsurfModifierFlag_UseCrease
@ eSubsurfModifierFlag_UseCustomNormals
Object is a sort of wrapper for general info.
@ USER_GPU_FLAG_SUBDIVISION_EVALUATION
int GPU_max_compute_shader_storage_blocks()
GPUBackendType GPU_backend_get_type()
Read Guarded memory(de)allocation.
#define U
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
FVarLinearInterpolation fvar_interpolation_from_uv_smooth(int uv_smooth)
Definition subdiv.cc:47
VtxBoundaryInterpolation vtx_boundary_interpolation_from_subsurf(int boundary_smooth)
Definition subdiv.cc:67
Subdiv * update_from_mesh(Subdiv *subdiv, const Settings *settings, const Mesh *mesh)
Definition subdiv.cc:179
blender::bke::subdiv::Settings settings
blender::bke::subdiv::Subdiv * subdiv_cpu
blender::bke::subdiv::Subdiv * subdiv_gpu
VtxBoundaryInterpolation vtx_boundary_interpolation
Definition BKE_subdiv.hh:77
FVarLinearInterpolation fvar_linear_interpolation
Definition BKE_subdiv.hh:78
bool BKE_subsurf_modifier_can_do_gpu_subdiv(const SubsurfModifierData *smd, const Mesh *mesh)
int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode)
bool BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(const SubsurfModifierData *smd, const Mesh *mesh)
bool BKE_subsurf_modifier_has_split_normals(const SubsurfModifierData *smd, const Mesh *mesh)
bool BKE_subsurf_modifier_runtime_init(SubsurfModifierData *smd, const bool use_render_params)
bool BKE_subsurf_modifier_use_custom_loop_normals(const SubsurfModifierData *smd, const Mesh *mesh)
static bool is_subdivision_evaluation_possible_on_gpu()
subdiv::Settings BKE_subsurf_modifier_settings_init(const SubsurfModifierData *smd, const bool use_render_params)
subdiv::Subdiv * BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtime_data, const Mesh *mesh, const bool for_draw_code)