From 0c7dcc9be97d80d692cddc33ccf7f8544e0d6fb3 Mon Sep 17 00:00:00 2001 From: Dennis Tsiang Date: Thu, 25 Nov 2021 15:30:46 +0000 Subject: [PATCH] Fix bug in has_descendant_started_presenting in headless backend If there exists two swapchains where one is a descendant of another, we need to return VK_ERROR_OUT_OF_DATE_KHR error if the application tries to present from the ancestor when the descendant has started presenting. The has_descendant_started_presenting() function checks whether the descendant has started presenting by looking for pending images in the descendant's list of swapchain images. However, the descendant could have already presented its pending image(s) before the ancestor arrives at this check. In this scenario, the descendant will have marked the swapchain image(s) as now free, and therefore when the ancestor looks for pending images it will fail to find any. This causes the function to incorrectly return false. This bug can be resolved by creating a new boolean member variable to track whether the swapchain has started presenting. Change-Id: Ibc3399a4bb05f89940f0b595d25aa07b8e2a2cb8 Signed-off-by: Dennis Tsiang Signed-off-by: Normunds Rieksts --- wsi/swapchain_base.cpp | 12 +++--------- wsi/swapchain_base.hpp | 7 ++++++- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/wsi/swapchain_base.cpp b/wsi/swapchain_base.cpp index b04dc79..ab24f0b 100644 --- a/wsi/swapchain_base.cpp +++ b/wsi/swapchain_base.cpp @@ -131,15 +131,7 @@ bool swapchain_base::has_descendant_started_presenting() } auto *desc = reinterpret_cast(m_descendant); - for (auto &image : desc->m_swapchain_images) - { - if (image.status == swapchain_image::PRESENTED || image.status == swapchain_image::PENDING) - { - return true; - } - } - - return false; + return desc->m_started_presenting; } VkResult swapchain_base::init_page_flip_thread() @@ -194,6 +186,7 @@ swapchain_base::swapchain_base(layer::device_private_data &dev_data, const VkAll , m_queue(VK_NULL_HANDLE) , m_image_acquire_lock() , m_error_state(VK_NOT_READY) + , m_started_presenting(false) { } @@ -486,6 +479,7 @@ VkResult swapchain_base::notify_presentation_engine(uint32_t image_index) } m_swapchain_images[image_index].status = swapchain_image::PENDING; + m_started_presenting = true; if (m_page_flip_thread_run) { diff --git a/wsi/swapchain_base.hpp b/wsi/swapchain_base.hpp index fabc069..c8d5573 100644 --- a/wsi/swapchain_base.hpp +++ b/wsi/swapchain_base.hpp @@ -513,7 +513,7 @@ private: void call_present(uint32_t image_index); /** - * @brief Return true if the descendant has an image with PENDING or PRESENTED status. + * @brief Return true if the descendant has started presenting. */ bool has_descendant_started_presenting(); @@ -536,6 +536,11 @@ private: * @return VK_SUCCESS on success or an error code otherwise. */ VkResult notify_presentation_engine(uint32_t image_index); + + /** + * @brief A flag to track if swapchain has started presenting. + */ + bool m_started_presenting; }; } /* namespace wsi */ -- 2.7.4