From: Roman Gilg Date: Mon, 31 Aug 2020 09:35:16 +0000 (+0200) Subject: vulkan/wsi/x11: wait for acquirable images in FIFO mode X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=ec5e918ef4911d09b5611773bc58952b13ccef38 vulkan/wsi/x11: wait for acquirable images in FIFO mode In FIFO presentation mode we block either on our present-queue or on Present events after an image was transmitted. In case we receive completion events without idle events at some point we exhaust our acquire-queue and can not block anymore on present-queue. Ensure that the consumer has at least one image to acquire before blocking again on present-queue. Otherwise wait for one from the X server. CC: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3344 Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Simon Ser Part-of: --- diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 2be3072587a..961704f2057 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -1145,11 +1145,9 @@ x11_manage_fifo_queues(void *state) assert(chain->has_present_queue); while (chain->status >= 0) { - /* It should be safe to unconditionally block here. Later in the loop - * we blocks until the previous present has landed on-screen. At that - * point, we should have received IDLE_NOTIFY on all images presented - * before that point so the client should be able to acquire any image - * other than the currently presented one. + /* We can block here unconditionally because after an image was sent to + * the server (later on in this loop) we ensure at least one image is + * acquirable by the consumer or wait there on such an event. */ uint32_t image_index = 0; result = wsi_queue_pull(&chain->present_queue, &image_index, INT64_MAX); @@ -1182,7 +1180,12 @@ x11_manage_fifo_queues(void *state) goto fail; if (chain->has_acquire_queue) { - while (chain->last_present_msc < target_msc) { + /* Wait for our presentation to occur and ensure we have at least one + * image that can be acquired by the client afterwards. This ensures we + * can pull on the present-queue on the next loop. + */ + while (chain->last_present_msc < target_msc || + chain->sent_image_count == chain->base.image_count) { xcb_generic_event_t *event = xcb_wait_for_special_event(chain->conn, chain->special_event); if (!event) {