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 | |
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.
-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; } |