Add support for VkSwapchainPresentFenceInfoEXT

Extends queue_submit to handle the fences passed by the application
through VkSwapchainPresentFenceInfoEXT.

Change-Id: If3f44e2634cc771ee7d01589a59a95d0f86f99df
Signed-off-by: Iason Paraskevopoulos <iason.paraskevopoulos@arm.com>
Signed-off-by: Fufu Fang <fufu.fang@arm.com>
This commit is contained in:
Iason Paraskevopoulos 2024-04-09 16:14:27 +01:00 committed by Fufu Fang
parent 01b4e9aeff
commit 4adaa0b5eb
3 changed files with 39 additions and 10 deletions

View file

@ -162,13 +162,16 @@ wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)
/* Avoid allocating on the heap when there is only one swapchain. */
const VkPresentInfoKHR *present_info = pPresentInfo;
bool use_image_present_semaphore = false;
if (pPresentInfo->swapchainCount > 1)
{
TRY_LOG_CALL(submit_wait_request(queue, *pPresentInfo, device_data));
present_info = nullptr;
use_image_present_semaphore = true;
}
VkResult ret = VK_SUCCESS;
const auto present_fence_info = util::find_extension<VkSwapchainPresentFenceInfoEXT>(
VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_EXT, present_info->pNext);
for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i)
{
VkSwapchainKHR swapc = pPresentInfo->pSwapchains[i];
@ -176,7 +179,9 @@ wsi_layer_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo)
auto *sc = reinterpret_cast<wsi::swapchain_base *>(swapc);
assert(sc != nullptr);
VkResult res = sc->queue_present(queue, present_info, pPresentInfo->pImageIndices[i]);
const VkFence present_fence = (present_fence_info == nullptr) ? VK_NULL_HANDLE : present_fence_info->pFences[i];
VkResult res = sc->queue_present(queue, present_info, pPresentInfo->pImageIndices[i], use_image_present_semaphore,
present_fence);
if (pPresentInfo->pResults != nullptr)
{
pPresentInfo->pResults[i] = res;

View file

@ -299,6 +299,8 @@ VkResult swapchain_base::init(VkDevice device, const VkSwapchainCreateInfoKHR *s
TRY_LOG_CALL(m_device_data.disp.CreateSemaphore(m_device, &semaphore_info, get_allocation_callbacks(),
&img.present_semaphore));
TRY_LOG_CALL(m_device_data.disp.CreateSemaphore(m_device, &semaphore_info, get_allocation_callbacks(),
&img.present_fence_wait));
}
m_device_data.disp.GetDeviceQueue(m_device, 0, 0, &m_queue);
@ -400,6 +402,7 @@ void swapchain_base::teardown()
destroy_image(img);
m_device_data.disp.DestroySemaphore(m_device, img.present_semaphore, get_allocation_callbacks());
m_device_data.disp.DestroySemaphore(m_device, img.present_fence_wait, get_allocation_callbacks());
}
}
@ -583,12 +586,13 @@ VkResult swapchain_base::notify_presentation_engine(uint32_t image_index)
return VK_SUCCESS;
}
VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *present_info, const uint32_t image_index)
VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *present_info, const uint32_t image_index,
bool use_image_present_semaphore, const VkFence present_fence)
{
const VkSemaphore *wait_semaphores = &m_swapchain_images[image_index].present_semaphore;
uint32_t sem_count = 1;
if (present_info != nullptr)
if (!use_image_present_semaphore)
{
wait_semaphores = present_info->pWaitSemaphores;
sem_count = present_info->waitSemaphoreCount;
@ -601,10 +605,24 @@ VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *pr
TRY_LOG_CALL(image_wait_present(m_swapchain_images[image_index], WAIT_PRESENT_TIMEOUT));
}
queue_submit_semaphores semaphores = { wait_semaphores, sem_count, nullptr, 0 };
queue_submit_semaphores semaphores = {
wait_semaphores,
sem_count,
(present_fence != VK_NULL_HANDLE) ? &m_swapchain_images[image_index].present_fence_wait : nullptr,
(present_fence != VK_NULL_HANDLE) ? 1u : 0,
};
TRY_LOG_CALL(image_set_present_payload(m_swapchain_images[image_index], queue, semaphores));
if (present_fence != VK_NULL_HANDLE)
{
const queue_submit_semaphores wait_semaphores = { &m_swapchain_images[image_index].present_fence_wait, 1, nullptr,
0 };
/*
* Here we chain wait_semaphores with present_fence through present_fence_wait.
*/
TRY(sync_queue_submit(m_device_data, queue, present_fence, wait_semaphores));
}
TRY(notify_presentation_engine(image_index));
return VK_SUCCESS;

View file

@ -66,6 +66,7 @@ struct swapchain_image
VkImage image{ VK_NULL_HANDLE };
status status{ swapchain_image::INVALID };
VkSemaphore present_semaphore{ VK_NULL_HANDLE };
VkSemaphore present_fence_wait{ VK_NULL_HANDLE };
};
#if WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN
@ -140,17 +141,22 @@ public:
* @param queue The queue to which the submission will be made to.
*
* @param present_info Information about the swapchain and image to be presented.
* If it is nullptr it means that the presentation request will wait on the
* image's \p present_semaphore and not the semaphores that come with
* \p present_info.
*
* @param imageIndex The index of the image to be presented.
*
* @param use_image_present_semaphore Flag that indicates whether the presentation
* request will wait on the image's \p present_semaphore
* and not the semaphores that come with
* \p present_info.
*
* @param present_fence Fence supplied by the application with VkSwapchainPresentFenceInfoEXT.
*
* @return If queue submission fails returns error of vkQueueSubmit, if the
* swapchain has a descendant who started presenting returns VK_ERROR_OUT_OF_DATE_KHR,
* otherwise returns VK_SUCCESS.
*/
VkResult queue_present(VkQueue queue, const VkPresentInfoKHR *present_info, const uint32_t image_index);
VkResult queue_present(VkQueue queue, const VkPresentInfoKHR *present_info, const uint32_t image_index,
bool use_image_present_semaphore, const VkFence present_fence);
/**
* @brief Get the allocator