diff --git a/src/vulkan/wsi/wsi_common_headless.c b/src/vulkan/wsi/wsi_common_headless.c index a3510cce5bd..e7ceb24034a 100644 --- a/src/vulkan/wsi/wsi_common_headless.c +++ b/src/vulkan/wsi/wsi_common_headless.c @@ -241,7 +241,18 @@ wsi_headless_surface_get_present_rectangles(VkIcdSurfaceBase *surface, struct wsi_headless_image { struct wsi_image base; - bool busy; + + /* whether the host side ownership is taken by the app or the display */ + bool busy_on_host; + + /* whether the image may still be worked on by the device + * + * The headless display does not involve a presentation queue to wait for + * the gpu out-fence. To let the app acquire the most likely idle image, we + * use a second boolean to steer the app to acquire all the swapchain images + * in a loop. + */ + bool busy_on_device; }; struct wsi_headless_swapchain { @@ -278,10 +289,17 @@ wsi_headless_swapchain_acquire_next_image(struct wsi_swapchain *wsi_chain, while (1) { /* Try to find a free image. */ for (uint32_t i = 0; i < chain->base.image_count; i++) { - if (!chain->images[i].busy) { + if (!chain->images[i].busy_on_host) { + if (chain->images[i].busy_on_device) { + /* simple trick to avoid the just presented image */ + chain->images[i].busy_on_device = false; + continue; + } + /* We found a non-busy image */ *image_index = i; - chain->images[i].busy = true; + chain->images[i].busy_on_host = true; + chain->images[i].busy_on_device = true; return VK_SUCCESS; } } @@ -305,7 +323,7 @@ wsi_headless_swapchain_queue_present(struct wsi_swapchain *wsi_chain, assert(image_index < chain->base.image_count); - chain->images[image_index].busy = false; + chain->images[image_index].busy_on_host = false; return VK_SUCCESS; } @@ -501,7 +519,8 @@ wsi_headless_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, if (result != VK_SUCCESS) goto fail; - chain->images[i].busy = false; + chain->images[i].busy_on_host = false; + chain->images[i].busy_on_device = false; } *swapchain_out = &chain->base;