forked from blender/blender
me-main #1
@ -32,8 +32,13 @@ typedef struct SubsurfRuntimeData {
|
|||||||
SubdivSettings settings;
|
SubdivSettings settings;
|
||||||
|
|
||||||
/* Cached subdivision surface descriptor, with topology and settings. */
|
/* Cached subdivision surface descriptor, with topology and settings. */
|
||||||
struct Subdiv *subdiv;
|
struct Subdiv *subdiv_cpu;
|
||||||
bool set_by_draw_code;
|
struct Subdiv *subdiv_gpu;
|
||||||
|
|
||||||
|
/* Recent usage markers for UI diagnostics. To avoid UI flicker due to races
|
||||||
|
* between evaluation and UI redraw, they are set to 2 when an evaluator is used,
|
||||||
|
* and count down every frame. */
|
||||||
|
char used_cpu, used_gpu;
|
||||||
|
|
||||||
/* Cached mesh wrapper data, to be used for GPU subdiv or lazy evaluation on CPU. */
|
/* Cached mesh wrapper data, to be used for GPU subdiv or lazy evaluation on CPU. */
|
||||||
bool has_gpu_subdiv;
|
bool has_gpu_subdiv;
|
||||||
|
@ -350,7 +350,7 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
|
|||||||
BKE_mesh_calc_normals_split(subdiv_mesh);
|
BKE_mesh_calc_normals_split(subdiv_mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subdiv != runtime_data->subdiv) {
|
if (subdiv != runtime_data->subdiv_cpu && subdiv != runtime_data->subdiv_gpu) {
|
||||||
BKE_subdiv_free(subdiv);
|
BKE_subdiv_free(subdiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ bool BKE_subsurf_modifier_runtime_init(SubsurfModifierData *smd, const bool use_
|
|||||||
* was already allocated. */
|
* was already allocated. */
|
||||||
if (runtime_data) {
|
if (runtime_data) {
|
||||||
runtime_data->settings = settings;
|
runtime_data->settings = settings;
|
||||||
|
|
||||||
|
runtime_data->used_cpu = runtime_data->used_gpu = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -162,15 +164,18 @@ Subdiv *BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtim
|
|||||||
const Mesh *mesh,
|
const Mesh *mesh,
|
||||||
const bool for_draw_code)
|
const bool for_draw_code)
|
||||||
{
|
{
|
||||||
if (runtime_data->subdiv && runtime_data->set_by_draw_code != for_draw_code) {
|
if (for_draw_code) {
|
||||||
BKE_subdiv_free(runtime_data->subdiv);
|
runtime_data->used_gpu = 2; /* countdown in frames */
|
||||||
runtime_data->subdiv = nullptr;
|
|
||||||
|
return runtime_data->subdiv_gpu = BKE_subdiv_update_from_mesh(
|
||||||
|
runtime_data->subdiv_gpu, &runtime_data->settings, mesh);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
runtime_data->used_cpu = 2;
|
||||||
|
|
||||||
|
return runtime_data->subdiv_cpu = BKE_subdiv_update_from_mesh(
|
||||||
|
runtime_data->subdiv_cpu, &runtime_data->settings, mesh);
|
||||||
}
|
}
|
||||||
Subdiv *subdiv = BKE_subdiv_update_from_mesh(
|
|
||||||
runtime_data->subdiv, &runtime_data->settings, mesh);
|
|
||||||
runtime_data->subdiv = subdiv;
|
|
||||||
runtime_data->set_by_draw_code = for_draw_code;
|
|
||||||
return subdiv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode)
|
int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode)
|
||||||
|
@ -100,8 +100,11 @@ static void freeRuntimeData(void *runtime_data_v)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)runtime_data_v;
|
SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)runtime_data_v;
|
||||||
if (runtime_data->subdiv != nullptr) {
|
if (runtime_data->subdiv_cpu != nullptr) {
|
||||||
BKE_subdiv_free(runtime_data->subdiv);
|
BKE_subdiv_free(runtime_data->subdiv_cpu);
|
||||||
|
}
|
||||||
|
if (runtime_data->subdiv_gpu != nullptr) {
|
||||||
|
BKE_subdiv_free(runtime_data->subdiv_gpu);
|
||||||
}
|
}
|
||||||
MEM_freeN(runtime_data);
|
MEM_freeN(runtime_data);
|
||||||
}
|
}
|
||||||
@ -227,6 +230,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||||||
|
|
||||||
SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime;
|
SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime;
|
||||||
|
|
||||||
|
/* Decrement the recent usage counters. */
|
||||||
|
if (runtime_data->used_cpu) {
|
||||||
|
runtime_data->used_cpu--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runtime_data->used_gpu) {
|
||||||
|
runtime_data->used_gpu--;
|
||||||
|
}
|
||||||
|
|
||||||
/* Delay evaluation to the draw code if possible, provided we do not have to apply the modifier.
|
/* 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) {
|
if ((ctx->flag & MOD_APPLY_TO_BASE_MESH) == 0) {
|
||||||
@ -273,7 +285,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||||||
CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
|
CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
|
||||||
}
|
}
|
||||||
// BKE_subdiv_stats_print(&subdiv->stats);
|
// BKE_subdiv_stats_print(&subdiv->stats);
|
||||||
if (subdiv != runtime_data->subdiv) {
|
if (subdiv != runtime_data->subdiv_cpu && subdiv != runtime_data->subdiv_gpu) {
|
||||||
BKE_subdiv_free(subdiv);
|
BKE_subdiv_free(subdiv);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -305,7 +317,7 @@ static void deformMatrices(ModifierData *md,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, verts_num);
|
BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, verts_num);
|
||||||
if (subdiv != runtime_data->subdiv) {
|
if (subdiv != runtime_data->subdiv_cpu && subdiv != runtime_data->subdiv_gpu) {
|
||||||
BKE_subdiv_free(subdiv);
|
BKE_subdiv_free(subdiv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -409,12 +421,29 @@ static void panel_draw(const bContext *C, Panel *panel)
|
|||||||
|
|
||||||
uiItemR(layout, ptr, "show_only_control_edges", 0, nullptr, ICON_NONE);
|
uiItemR(layout, ptr, "show_only_control_edges", 0, nullptr, ICON_NONE);
|
||||||
|
|
||||||
|
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||||
SubsurfModifierData *smd = static_cast<SubsurfModifierData *>(ptr->data);
|
SubsurfModifierData *smd = static_cast<SubsurfModifierData *>(ptr->data);
|
||||||
const Object *ob = static_cast<const Object *>(ob_ptr.data);
|
Object *ob = static_cast<Object *>(ob_ptr.data);
|
||||||
const Mesh *mesh = static_cast<const Mesh *>(ob->data);
|
const Mesh *mesh = static_cast<const Mesh *>(ob->data);
|
||||||
if (BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(smd, mesh)) {
|
if (BKE_subsurf_modifier_force_disable_gpu_evaluation_for_mesh(smd, mesh)) {
|
||||||
uiItemL(layout, "Autosmooth or custom normals detected, disabling GPU subdivision", ICON_INFO);
|
uiItemL(layout, "Autosmooth or custom normals detected, disabling GPU subdivision", 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)) {
|
||||||
|
if (md_eval->type == eModifierType_Subsurf) {
|
||||||
|
SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)md_eval->runtime;
|
||||||
|
|
||||||
|
if (runtime_data && runtime_data->used_gpu) {
|
||||||
|
if (runtime_data->used_cpu) {
|
||||||
|
uiItemL(layout, "Using both CPU and GPU subdivision", ICON_INFO);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uiItemL(layout, "Using GPU subdivision", ICON_INFO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
modifier_panel_end(layout, ptr);
|
modifier_panel_end(layout, ptr);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user