From 153857fb64b7d2521a8b402854afed97bf247b39 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Wed, 21 May 2025 15:27:01 -0700 Subject: [PATCH] vulkan/wsi: amend barriers for blit dst buffer going to foreign queue The prime blit dst buffer can be backed by external memory, no matter host ptr shm or dma-buf export alloc. Whether the external path is taken is only decided upon blit ctx creation time, so we have to track whether external in the wsi_image. When the external path is taken, we have to explicitly handle queue family ownership transfer from internal to foreign. To be noted, no explicit foreign to internal ownership transfer is needed since the blit dst content can be left undefined. Reviewed-by: Hans-Kristian Arntzen Part-of: --- src/vulkan/wsi/wsi_common.c | 20 +++++++++++++++----- src/vulkan/wsi/wsi_common_private.h | 4 ++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index f4c23b19d55..d23dc993b18 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -1858,6 +1858,7 @@ wsi_create_buffer_blit_context(const struct wsi_swapchain *chain, VkExportMemoryAllocateInfo memory_export_info; VkImportMemoryHostPointerInfoEXT host_ptr_info; if (sw_host_ptr != NULL) { + image->blit.to_foreign_queue = true; host_ptr_info = (VkImportMemoryHostPointerInfoEXT) { .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT, .pHostPointer = sw_host_ptr, @@ -1865,6 +1866,7 @@ wsi_create_buffer_blit_context(const struct wsi_swapchain *chain, }; __vk_append_struct(&buf_mem_info, &host_ptr_info); } else if (handle_types != 0) { + image->blit.to_foreign_queue = true; memory_export_info = (VkExportMemoryAllocateInfo) { .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, .handleTypes = handle_types, @@ -1929,7 +1931,8 @@ static void wsi_cmd_blit_image_to_buffer(VkCommandBuffer cmd_buffer, const struct wsi_device *wsi, const struct wsi_image_info *info, - struct wsi_image *image) + struct wsi_image *image, + uint32_t qfi) { assert(info->image_type == WSI_IMAGE_TYPE_CPU || info->image_type == WSI_IMAGE_TYPE_DRM); @@ -1990,8 +1993,11 @@ wsi_cmd_blit_image_to_buffer(VkCommandBuffer cmd_buffer, .pNext = NULL, .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_HOST_READ_BIT, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .srcQueueFamilyIndex = + image->blit.to_foreign_queue ? qfi : VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = image->blit.to_foreign_queue + ? VK_QUEUE_FAMILY_FOREIGN_EXT + : VK_QUEUE_FAMILY_IGNORED, .buffer = image->blit.buffer, .offset = 0, .size = VK_WHOLE_SIZE, @@ -2144,9 +2150,13 @@ wsi_finish_create_blit_context(const struct wsi_swapchain *chain, wsi->BeginCommandBuffer(cmd_buffer, &begin_info); switch (chain->blit.type) { - case WSI_SWAPCHAIN_BUFFER_BLIT: - wsi_cmd_blit_image_to_buffer(cmd_buffer, wsi, info, image); + case WSI_SWAPCHAIN_BUFFER_BLIT: { + VK_FROM_HANDLE(vk_queue, blit_queue, chain->blit.queue); + wsi_cmd_blit_image_to_buffer( + cmd_buffer, wsi, info, image, + blit_queue ? blit_queue->queue_family_index : i); break; + } case WSI_SWAPCHAIN_IMAGE_BLIT: wsi_cmd_blit_image_to_image(cmd_buffer, wsi, info, image); break; diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h index e11f0058a99..f138fee5519 100644 --- a/src/vulkan/wsi/wsi_common_private.h +++ b/src/vulkan/wsi/wsi_common_private.h @@ -146,6 +146,10 @@ struct wsi_image { VkImage image; VkDeviceMemory memory; VkCommandBuffer *cmd_buffers; + /* Whether the backing memory of the blit dst buffer is shared directly + * with the compositor instead of being mapped via vkMapMemory locally. + */ + bool to_foreign_queue; } blit; /* Whether or not the image has been acquired * on the CPU side via acquire_next_image.