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:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2022-05-03 19:00:12 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2022-05-03 19:02:10 +0300
commit947f8ba300090027304680c624c6257c41417a6b (patch)
treedba89119d7a20b72c6db67036e44af095176a8da
parent5962db093f2f1fcf735ceaaa1ba6bbd25efc397f (diff)
Fix T96338: GPU subdiv crash switching to UV editing
The crash is caused as the data for the UV editor is requested before the data for the mesh as a separate draw update. Since building the UV stretch angle buffer requires the position buffer, the latter is not created yet in this case. To fix this, create a local position buffer from the subdivision data. An alternate fix was considered to remove the dependency on the position buffer by interpolating on the GPU the coarse stretch angle buffer but this did work. Maybe this will be revisited.
-rw-r--r--source/blender/draw/intern/draw_cache_impl_subdivision.cc11
-rw-r--r--source/blender/draw/intern/draw_subdivision.h5
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc19
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc13
4 files changed, 36 insertions, 12 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
index 7c72b77af1f..19745304b2d 100644
--- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc
+++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
@@ -366,6 +366,17 @@ static GPUVertFormat *get_origindex_format()
return &format;
}
+GPUVertFormat *draw_subdiv_get_pos_nor_format()
+{
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ GPU_vertformat_alias_add(&format, "vnor");
+ }
+ return &format;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h
index e5f64a99092..267a98f2d37 100644
--- a/source/blender/draw/intern/draw_subdivision.h
+++ b/source/blender/draw/intern/draw_subdivision.h
@@ -13,6 +13,7 @@ struct BMesh;
struct GPUIndexBuf;
struct GPUUniformBuf;
struct GPUVertBuf;
+struct GPUVertFormat;
struct Mesh;
struct MeshBatchCache;
struct MeshBufferCache;
@@ -284,6 +285,10 @@ void draw_subdiv_build_edituv_stretch_angle_buffer(const DRWSubdivCache *cache,
int uvs_offset,
struct GPUVertBuf *stretch_angles);
+/** Return the format used for the positions and normals VBO.
+ */
+struct GPUVertFormat *draw_subdiv_get_pos_nor_format();
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
index 0d422180288..4ced14ab11a 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
@@ -224,6 +224,21 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi
GPUVertBuf *pos_nor = cache->final.buff.vbo.pos_nor;
GPUVertBuf *uvs = cache->final.buff.vbo.uv;
+ /* It may happen that the data for the UV editor is requested before (as a separate draw update)
+ * the data for the mesh when switching to the `UV Editing` workspace, and therefore the position
+ * buffer might not be created yet. In this case, create a buffer it locally, the subdivision
+ * data should already be evaluated if we are here. This can happen if the subsurf modifier is
+ * only enabled in edit-mode. See T96338. */
+ if (!pos_nor) {
+ const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
+ pos_nor = GPU_vertbuf_calloc();
+ GPU_vertbuf_init_build_on_device(pos_nor,
+ draw_subdiv_get_pos_nor_format(),
+ subdiv_cache->num_subdiv_loops + loose_geom.loop_len);
+
+ draw_subdiv_extract_pos_nor(subdiv_cache, pos_nor);
+ }
+
/* UVs are stored contiguously so we need to compute the offset in the UVs buffer for the active
* UV layer. */
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_MESH) ? &mr->me->ldata : &mr->bm->ldata;
@@ -253,6 +268,10 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi
draw_subdiv_build_edituv_stretch_angle_buffer(
subdiv_cache, pos_nor, uvs, uvs_offset, refined_vbo);
+
+ if (!cache->final.buff.vbo.pos_nor) {
+ GPU_vertbuf_discard(pos_nor);
+ }
}
constexpr MeshExtract create_extractor_edituv_edituv_stretch_angle()
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
index dd056891a94..ea46d9c4caa 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
@@ -179,17 +179,6 @@ static void extract_pos_nor_finish(const MeshRenderData *UNUSED(mr),
MEM_freeN(data->normals);
}
-static GPUVertFormat *get_pos_nor_format()
-{
- static GPUVertFormat format = {0};
- if (format.attr_len == 0) {
- GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- GPU_vertformat_alias_add(&format, "vnor");
- }
- return &format;
-}
-
static GPUVertFormat *get_normals_format()
{
static GPUVertFormat format = {0};
@@ -221,7 +210,7 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
/* Initialize the vertex buffer, it was already allocated. */
GPU_vertbuf_init_build_on_device(
- vbo, get_pos_nor_format(), subdiv_cache->num_subdiv_loops + loose_geom.loop_len);
+ vbo, draw_subdiv_get_pos_nor_format(), subdiv_cache->num_subdiv_loops + loose_geom.loop_len);
if (subdiv_cache->num_subdiv_loops == 0) {
return;