diff options
author | Alexander Orzechowski <alex@ozal.ski> | 2023-08-20 20:55:03 -0400 |
---|---|---|
committer | Alexander Orzechowski <alex@ozal.ski> | 2023-08-20 21:12:06 -0400 |
commit | 5f6912595e922c30beaf99190634bd1747be8f87 (patch) | |
tree | c325b2a9bb68403769dedd7a1bbbe4b1664b0fd1 /render/vulkan | |
parent | bdc34401ba8e4a59b3464c17fa5acf43ca417e57 (diff) |
renderer/vulkan: Defer device lost signal until end of pass
If the compositor were to try to handle a GPU reset within the lost
signal (by recreating the renderer) we should avoid referencing renderer
resources after the lost signal. This prevents use after free for such
compositors.
Diffstat (limited to 'render/vulkan')
-rw-r--r-- | render/vulkan/pass.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index bfb3628f..505fd36a 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -69,6 +69,7 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { struct wlr_vk_render_buffer *render_buffer = pass->render_buffer; struct wlr_vk_command_buffer *stage_cb = NULL; VkSemaphoreSubmitInfoKHR *render_wait = NULL; + bool device_lost = false; if (pass->failed) { goto error; @@ -364,11 +365,9 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { VkSubmitInfo2KHR submit_info[] = { stage_submit, render_submit }; VkResult res = renderer->dev->api.vkQueueSubmit2KHR(renderer->dev->queue, 2, submit_info, VK_NULL_HANDLE); - if (res == VK_ERROR_DEVICE_LOST) { - wlr_log(WLR_ERROR, "vkQueueSubmit failed with VK_ERROR_DEVICE_LOST"); - wl_signal_emit_mutable(&renderer->wlr_renderer.events.lost, NULL); - goto error; - } else if (res != VK_SUCCESS) { + + if (res != VK_SUCCESS) { + device_lost = res == VK_ERROR_DEVICE_LOST; wlr_vk_error("vkQueueSubmit", res); goto error; } @@ -398,6 +397,11 @@ error: vulkan_reset_command_buffer(render_cb); wlr_buffer_unlock(render_buffer->wlr_buffer); free(pass); + + if (device_lost) { + wl_signal_emit_mutable(&renderer->wlr_renderer.events.lost, NULL); + } + return false; } |