Fix FD ownership issue in Wayland Vulkan import

When a file descriptor is imported in Vulkan as a dma buf the Vulkan
implementation takes ownership. We use this property to manage the
lifetime of file descriptors allocated by WSIALLOC by importing them as
VkDeviceMemory. After import the WSI Layer doesn't need to close any
file descriptors and instead only needs to destroy the VkDeviceMemory
object.

However after import the original file descriptor should not be used by
the application. Currently the WSI Layer Wayland implementation violates
this by using the FD to pass to the compositor. This commit fixes the
issue by initiating the Wayland requests before importing the fd.
Internally libwayland will duplicate the fd.

Change-Id: I3ca877f90f0139cf23b8b39c6024e8815b82d692
Signed-off-by: Dennis Tsiang <dennis.tsiang@arm.com>
This commit is contained in:
Dennis Tsiang 2022-01-24 15:02:03 +00:00
parent 79b5d296c2
commit e78252429a

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019, 2021 Arm Limited.
* Copyright (c) 2017-2019, 2021-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@ -28,7 +28,7 @@
#include "wl_helpers.hpp"
#include "surface_properties.hpp"
#include <stdint.h>
#include <cstdint>
#include <cstring>
#include <cassert>
#include <unistd.h>
@ -508,32 +508,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland
WSI_LOG_ERROR("Image creation failed.");
return result;
}
if (is_disjoint)
{
for (uint32_t plane = 0; plane < image_data->num_planes; plane++)
{
const auto fd_index = get_same_fd_index(image_data->buffer_fd[plane], image_data->buffer_fd);
if (fd_index == plane)
{
VkResult result = allocate_plane_memory(image_data->buffer_fd[plane], &image_data->memory[fd_index]);
if (result != VK_SUCCESS)
{
return result;
}
}
}
}
else
{
VkResult result = allocate_plane_memory(image_data->buffer_fd[0], &image_data->memory[0]);
if (result != VK_SUCCESS)
{
return result;
}
}
return internal_bind_swapchain_image(m_device, image_data, *image);
return result;
}
VkResult swapchain::create_and_bind_swapchain_image(VkImageCreateInfo image_create_info, swapchain_image &image)
@ -583,6 +558,36 @@ VkResult swapchain::create_and_bind_swapchain_image(VkImageCreateInfo image_crea
return VK_ERROR_INITIALIZATION_FAILED;
}
if (image_data->is_disjoint)
{
for (uint32_t plane = 0; plane < image_data->num_planes; plane++)
{
const auto fd_index = get_same_fd_index(image_data->buffer_fd[plane], image_data->buffer_fd);
if (fd_index == plane)
{
VkResult result = allocate_plane_memory(image_data->buffer_fd[plane], &image_data->memory[fd_index]);
if (result != VK_SUCCESS)
{
return result;
}
}
}
}
else
{
VkResult result = allocate_plane_memory(image_data->buffer_fd[0], &image_data->memory[0]);
if (result != VK_SUCCESS)
{
return result;
}
}
result = internal_bind_swapchain_image(m_device, image_data, image.image);
if (result != VK_SUCCESS)
{
return result;
}
/* Initialize presentation fence. */
auto present_fence = sync_fd_fence_sync::create(m_device_data);
if (!present_fence.has_value())