Support deferred allocation

Adds support for VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT,
by deferring calling create_and_bind_swapchain_image in
acquire_next_image. Also, adds a function for checking if a swapchain
image can be bound to memory when deferred has been selected.

Change-Id: I22e40260d6b06091cc704bca3bf2baa80370c589
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-15 21:09:09 +01:00 committed by Fufu Fang
parent 4adaa0b5eb
commit 9edb068a38
3 changed files with 39 additions and 1 deletions

View file

@ -342,6 +342,8 @@ wsi_layer_vkBindImageMemory2(VkDevice device, uint32_t bindInfoCount,
else
{
auto sc = reinterpret_cast<wsi::swapchain_base *>(bind_sc_info->swapchain);
TRY_LOG(sc->is_bind_allowed(bind_sc_info->imageIndex),
"Bind is not allowed on images that haven't been acquired first.");
result = sc->bind_swapchain_image(device, &pBindInfos[i], bind_sc_info);
error_message = "Failed to bind an image to the swapchain";
}

View file

@ -290,9 +290,19 @@ VkResult swapchain_base::init(VkDevice device, const VkSwapchainCreateInfoKHR *s
return result;
}
const bool image_deferred_allocation =
image_create_info.flags & VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT;
for (auto &img : m_swapchain_images)
{
TRY_LOG_CALL(create_and_bind_swapchain_image(image_create_info, img));
if (image_deferred_allocation)
{
m_image_create_info = image_create_info;
img.status = swapchain_image::UNALLOCATED;
}
else
{
TRY_LOG_CALL(create_and_bind_swapchain_image(image_create_info, img));
}
VkSemaphoreCreateInfo semaphore_info = {};
semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
@ -422,6 +432,16 @@ VkResult swapchain_base::acquire_next_image(uint64_t timeout, VkSemaphore semaph
size_t i;
for (i = 0; i < m_swapchain_images.size(); ++i)
{
if (m_swapchain_images[i].status == swapchain_image::UNALLOCATED)
{
auto res = create_and_bind_swapchain_image(m_image_create_info, m_swapchain_images[i]);
if (res != VK_SUCCESS)
{
WSI_LOG_ERROR("Failed to allocate swapchain image.");
return res != VK_ERROR_INITIALIZATION_FAILED ? res : VK_ERROR_OUT_OF_HOST_MEMORY;
}
}
if (m_swapchain_images[i].status == swapchain_image::FREE)
{
m_swapchain_images[i].status = swapchain_image::ACQUIRED;
@ -716,4 +736,10 @@ void swapchain_base::release_images(uint32_t image_count, const uint32_t *indice
}
}
VkResult swapchain_base::is_bind_allowed(uint32_t image_index) const
{
return m_swapchain_images[image_index].status != swapchain_image::UNALLOCATED ? VK_SUCCESS :
VK_ERROR_OUT_OF_HOST_MEMORY;
}
} /* namespace wsi */

View file

@ -58,6 +58,7 @@ struct swapchain_image
PENDING,
PRESENTED,
FREE,
UNALLOCATED,
};
/* Implementation specific data */
@ -229,6 +230,15 @@ public:
*/
void release_images(uint32_t image_count, const uint32_t *indices);
/**
* @brief Check if bind is allowed for a swapchain image.
*
* @param image_index The image's index.
*
* @return VK_SUCCESS on success, an error code otherwise.
*/
VkResult is_bind_allowed(uint32_t image_index) const;
protected:
layer::device_private_data &m_device_data;