diff --git a/.pick_status.json b/.pick_status.json index e5c50ae1622..b7cf4de2c88 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -769,7 +769,7 @@ "description": "vulkan/wsi/x11: wait for acquirable images in FIFO mode", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": null }, diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index da02569e94b..4cc03640ef2 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -1112,11 +1112,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); @@ -1149,7 +1147,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) {