diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2021-01-30 18:56:38 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2021-01-30 18:56:38 +0300 |
commit | 38bb26342227759e8e2ccd98e1b4e800ca141fb2 (patch) | |
tree | 8d3d829e487b33cea73e495336f41e10a73b347b /source/blender/draw/engines/eevee | |
parent | 3a954af862038affb86daa8dbaa7a5b7d7687e4b (diff) |
Fix T81193 EEVEE: Crash when motion blur is aborted at cache finish
This was caused by a use after free. The issue was that the motion steps
were successfully gathered but failling the last vertex count check,
discarding the copied VBOs but not removing the reference of the first
VBO which was passing the test.
Diffstat (limited to 'source/blender/draw/engines/eevee')
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_motion_blur.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index 59842ec50f7..8dcab579603 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -376,6 +376,19 @@ void EEVEE_motion_blur_cache_populate(EEVEE_ViewLayerData *UNUSED(sldata), } } +static void motion_blur_remove_vbo_reference_from_batch(GPUBatch *batch, + GPUVertBuf *vbo1, + GPUVertBuf *vbo2) +{ + + for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN; i++) { + if (ELEM(batch->verts[i], vbo1, vbo2)) { + /* Avoid double reference of the VBOs. */ + batch->verts[i] = NULL; + } + } +} + void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata) { EEVEE_StorageList *stl = vedata->stl; @@ -446,6 +459,9 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata) } if (mb_geom->use_deform == false) { + motion_blur_remove_vbo_reference_from_batch( + batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]); + GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_PREV]); GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_NEXT]); break; @@ -523,12 +539,8 @@ void EEVEE_motion_blur_swap_data(EEVEE_Data *vedata) case EEVEE_MOTION_DATA_MESH: if (mb_geom->batch != NULL) { - for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN; i++) { - if (ELEM(mb_geom->batch->verts[i], mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT])) { - /* Avoid double reference of the VBOs. */ - mb_geom->batch->verts[i] = NULL; - } - } + motion_blur_remove_vbo_reference_from_batch( + mb_geom->batch, mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT]); } GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_PREV]); mb_geom->vbo[MB_PREV] = mb_geom->vbo[MB_NEXT]; |