From 5f6912595e922c30beaf99190634bd1747be8f87 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Sun, 20 Aug 2023 20:55:03 -0400 Subject: [PATCH] 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. --- render/vulkan/pass.c | 14 +++++++++----- 1 file 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; }