aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Orzechowski <alex@ozal.ski>2023-08-20 20:55:03 -0400
committerAlexander Orzechowski <alex@ozal.ski>2023-08-20 21:12:06 -0400
commit5f6912595e922c30beaf99190634bd1747be8f87 (patch)
treec325b2a9bb68403769dedd7a1bbbe4b1664b0fd1
parentbdc34401ba8e4a59b3464c17fa5acf43ca417e57 (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.c14
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;
}