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 <post@arntzen-software.no>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35034>
This commit is contained in:
Yiwei Zhang 2025-05-21 15:27:01 -07:00 committed by Marge Bot
parent f6bf5d9a3e
commit 153857fb64
2 changed files with 19 additions and 5 deletions

View file

@ -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;

View file

@ -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.