diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2021-05-04 23:30:10 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2021-05-04 23:58:43 +0300 |
commit | 96abe5ebbc55323fc28ee4f6a852c912298c72d1 (patch) | |
tree | c5b744a1a654a24a94381d7e4b95df985e3b0ede /source/blender | |
parent | d28c46183d8890114784692d0ebee27d4cc2cff9 (diff) |
DRW: Fix issue with batch reusing freed VBO indices.
Some discard of vertbuf were not correctly followed by discards of
the GPUBatches that were using them. This lead to a use-after-free
situation where GPUBatches would reuse old VBO information. This did
not crash immediatly because the VBO indices were cached by our VAO
caching system. It kept working on some implementation because VBO
reference in the VAO (probably) preventing the VBO from being freed
by reference counting.
This fixes T85977 NVidia: Random crashes in 'DrvPresentBuffers'
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index f11fd0f3906..af54b57b162 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -557,12 +557,18 @@ static void mesh_batch_cache_discard_surface_batches(MeshBatchCache *cache) static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache) { FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) { - GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.pos_nor); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.uv); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.tan); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.vcol); GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.orco); } + /* Discard batches using vbo.uv. */ + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces); + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_stretch_area); + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_faces_stretch_angle); + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_edges); + GPU_BATCH_DISCARD_SAFE(cache->batch.edituv_verts); + mesh_batch_cache_discard_surface_batches(cache); mesh_cd_layers_type_clear(&cache->cd_used); } @@ -659,8 +665,17 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode) GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.lnor); } GPU_BATCH_DISCARD_SAFE(cache->batch.surface); + /* Discard batches using vbo.pos_nor. */ GPU_BATCH_DISCARD_SAFE(cache->batch.wire_loops); GPU_BATCH_DISCARD_SAFE(cache->batch.wire_edges); + GPU_BATCH_DISCARD_SAFE(cache->batch.all_verts); + GPU_BATCH_DISCARD_SAFE(cache->batch.all_edges); + GPU_BATCH_DISCARD_SAFE(cache->batch.loose_edges); + GPU_BATCH_DISCARD_SAFE(cache->batch.edge_detection); + GPU_BATCH_DISCARD_SAFE(cache->batch.surface_weights); + GPU_BATCH_DISCARD_SAFE(cache->batch.edit_mesh_analysis); + /* Discard batches using vbo.lnor. */ + GPU_BATCH_DISCARD_SAFE(cache->batch.edit_lnor); mesh_batch_cache_discard_surface_batches(cache); cache->batch_ready &= ~(MBC_SURFACE | MBC_WIRE_EDGES | MBC_WIRE_LOOPS); break; |