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
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2022-06-13 16:21:05 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-06-14 15:54:25 +0300
commitca9d65cc97ba8e872a0ef456e51dacadd06e237e (patch)
tree146e6457b8bc16563cb528ce2d43c5c93506e0db /source/blender/draw
parent4e96d71ddba8a5879337833ff7d63de12cf719a8 (diff)
Fix T98813: crash with GPU subdiv in edit mode and instanced geometry
Instancing with geometry nodes uses just the evaluated Mesh, and ignores the Object that it came from. That meant that it would try to look up the subsurf modifier on the instancer object which does not have the subsurf modifier. Instead of storing a session UUID and looking up the modifier data, store a point to the subsurf modifier runtime data. Unlike the modifier data, this runtime data is preserved across depsgraph CoW. It must be for the subdiv descriptor contained in it to stay valid along with the draw cache. As a bonus, this moves various Mesh_Runtime variables into the subsurf runtime data, reducing memory usage for meshes not using subdivision surfaces. Also fixes T98693, issues with subdivision level >= 8 due to integer overflow. Differential Revision: https://developer.blender.org/D15184
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.cc3
-rw-r--r--source/blender/draw/intern/draw_cache_impl_subdivision.cc50
-rw-r--r--source/blender/draw/intern/draw_subdivision.h3
3 files changed, 19 insertions, 37 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc
index 96b5910072b..7c02ee2c033 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc
@@ -2068,8 +2068,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
}
if (do_subdivision) {
- DRW_create_subdivision(scene,
- ob,
+ DRW_create_subdivision(ob,
me,
cache,
&cache->final,
diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
index 2b0953b0b9b..b37a420b555 100644
--- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc
+++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
@@ -1052,14 +1052,10 @@ static void build_vertex_face_adjacency_maps(DRWSubdivCache *cache)
static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
Subdiv *subdiv,
Mesh *mesh_eval,
- const Scene *scene,
- const SubsurfModifierData *smd,
- const bool is_final_render)
+ const SubsurfRuntimeData *runtime_data)
{
- const int requested_levels = (is_final_render) ? smd->renderLevels : smd->levels;
- const int level = get_render_subsurf_level(&scene->r, requested_levels, is_final_render);
SubdivToMeshSettings to_mesh_settings;
- to_mesh_settings.resolution = (1 << level) + 1;
+ to_mesh_settings.resolution = runtime_data->resolution;
to_mesh_settings.use_optimal_display = false;
if (cache->resolution != to_mesh_settings.resolution) {
@@ -2006,8 +2002,7 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache,
MEM_freeN(per_polygon_mat_offset);
}
-static bool draw_subdiv_create_requested_buffers(const Scene *scene,
- Object *ob,
+static bool draw_subdiv_create_requested_buffers(Object *ob,
Mesh *mesh,
struct MeshBatchCache *batch_cache,
MeshBufferCache *mbc,
@@ -2021,16 +2016,10 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene,
const bool use_hide,
OpenSubdiv_EvaluatorCache *evaluator_cache)
{
- SubsurfModifierData *smd = reinterpret_cast<SubsurfModifierData *>(
- BKE_modifiers_findby_session_uuid(ob, &mesh->runtime.subsurf_session_uuid));
- BLI_assert(smd);
+ SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data;
+ BLI_assert(runtime_data && runtime_data->has_gpu_subdiv);
- const bool is_final_render = DRW_state_is_scene_render();
-
- SubdivSettings settings;
- BKE_subsurf_modifier_subdiv_settings_init(&settings, smd, is_final_render);
-
- if (settings.level == 0) {
+ if (runtime_data->settings.level == 0) {
return false;
}
@@ -2041,9 +2030,7 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene,
bm = mesh->edit_mesh->bm;
}
- BKE_subsurf_modifier_ensure_runtime(smd);
-
- Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(smd, &settings, mesh_eval, true);
+ Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(runtime_data, mesh_eval, true);
if (!subdiv) {
return false;
}
@@ -2064,13 +2051,13 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene,
}
DRWSubdivCache *draw_cache = mesh_batch_cache_ensure_subdiv_cache(batch_cache);
- if (!draw_subdiv_build_cache(draw_cache, subdiv, mesh_eval, scene, smd, is_final_render)) {
+ if (!draw_subdiv_build_cache(draw_cache, subdiv, mesh_eval, runtime_data)) {
return false;
}
/* Edges which do not come from coarse edges should not be drawn in edit mode, only in object
* mode when optimal display in turned off. */
- const bool optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges) || is_editmode;
+ const bool optimal_display = runtime_data->use_optimal_display || is_editmode;
draw_cache->bm = bm;
draw_cache->mesh = mesh_eval;
@@ -2078,14 +2065,13 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene,
draw_cache->optimal_display = optimal_display;
draw_cache->num_subdiv_triangles = tris_count_from_number_of_loops(draw_cache->num_subdiv_loops);
- /* Copy topology information for stats display. Use `mesh` directly, as `mesh_eval` could be the
- * edit mesh. */
- mesh->runtime.subsurf_totvert = draw_cache->num_subdiv_verts;
- mesh->runtime.subsurf_totedge = draw_cache->num_subdiv_edges;
- mesh->runtime.subsurf_totpoly = draw_cache->num_subdiv_quads;
- mesh->runtime.subsurf_totloop = draw_cache->num_subdiv_loops;
+ /* Copy topology information for stats display. */
+ runtime_data->stats_totvert = draw_cache->num_subdiv_verts;
+ runtime_data->stats_totedge = draw_cache->num_subdiv_edges;
+ runtime_data->stats_totpoly = draw_cache->num_subdiv_quads;
+ runtime_data->stats_totloop = draw_cache->num_subdiv_loops;
- draw_cache->use_custom_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) &&
+ draw_cache->use_custom_loop_normals = (runtime_data->use_loop_normals) &&
(mesh_eval->flag & ME_AUTOSMOOTH) &&
CustomData_has_layer(&mesh_eval->ldata,
CD_CUSTOMLOOPNORMAL);
@@ -2207,8 +2193,7 @@ blender::Span<DRWSubdivLooseVertex> draw_subdiv_cache_get_loose_verts(const DRWS
static OpenSubdiv_EvaluatorCache *g_evaluator_cache = nullptr;
-void DRW_create_subdivision(const Scene *scene,
- Object *ob,
+void DRW_create_subdivision(Object *ob,
Mesh *mesh,
struct MeshBatchCache *batch_cache,
MeshBufferCache *mbc,
@@ -2231,8 +2216,7 @@ void DRW_create_subdivision(const Scene *scene,
const double begin_time = PIL_check_seconds_timer();
#endif
- if (!draw_subdiv_create_requested_buffers(scene,
- ob,
+ if (!draw_subdiv_create_requested_buffers(ob,
mesh,
batch_cache,
mbc,
diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h
index 8920a2dcd51..2d9f4713feb 100644
--- a/source/blender/draw/intern/draw_subdivision.h
+++ b/source/blender/draw/intern/draw_subdivision.h
@@ -185,8 +185,7 @@ void draw_subdiv_cache_free(DRWSubdivCache *cache);
/** \} */
-void DRW_create_subdivision(const struct Scene *scene,
- struct Object *ob,
+void DRW_create_subdivision(struct Object *ob,
struct Mesh *mesh,
struct MeshBatchCache *batch_cache,
struct MeshBufferCache *mbc,