From a377d32fdc4dd878497fabe6d338f6862c198b29 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Mon, 31 Oct 2022 13:44:29 -0700 Subject: [PATCH] vulkan/wsi: Add a test for kernel 6.0 sync file import/export ioctls. We'll use this in DRM WSI to decide if we need the implicit_sync flag on swapchain image creation. Part-of: --- src/vulkan/wsi/wsi_common.h | 3 ++ src/vulkan/wsi/wsi_common_drm.c | 78 +++++++++++++++++++++++++++++ src/vulkan/wsi/wsi_common_private.h | 1 + 3 files changed, 82 insertions(+) diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 6e714debd95..e3764939292 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -122,6 +122,9 @@ struct wsi_device { VkPresentModeKHR override_present_mode; bool force_bgra8_unorm_first; + /* Cached result for wsi_drm_check_dma_buf_sync_file_import_export(). */ + uint32_t cached_sync_file_import_export_result; + /* Whether to enable adaptive sync for a swapchain if implemented and * available. Not all window systems might support this. */ bool enable_adaptive_sync; diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c index d4013ed51a4..099c3150c29 100644 --- a/src/vulkan/wsi/wsi_common_drm.c +++ b/src/vulkan/wsi/wsi_common_drm.c @@ -24,8 +24,10 @@ #include "wsi_common_private.h" #include "wsi_common_drm.h" #include "util/macros.h" +#include "util/log.h" #include "util/os_file.h" #include "util/log.h" +#include "util/u_atomic.h" #include "util/xmlconfig.h" #include "vk_device.h" #include "vk_physical_device.h" @@ -96,6 +98,82 @@ wsi_dma_buf_import_sync_file(int dma_buf_fd, int sync_file_fd) return VK_SUCCESS; } +/** + * Returns whether we can do import/export of fences from dma-bufs. + * + * This should return success on linux 6.0+. + */ +static VkResult +wsi_drm_check_dma_buf_sync_file_import_export(const struct wsi_device *wsi, VkDevice device) +{ + /* Not doing a mutex here -- we may race to do the check twice, but it's + * lockless normally. + */ + uint32_t cached_result = p_atomic_read(&wsi->cached_sync_file_import_export_result); + if (likely(cached_result != 0)) + return (VkResult) (cached_result + 1); + + struct VkExportMemoryAllocateInfo export_info = { + .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + struct VkMemoryAllocateInfo mem_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = 4096, + .pNext = (void *)&export_info}; + VkResult result; + VkDeviceMemory mem; + result = wsi->AllocateMemory(device, &mem_info, NULL, &mem); + if (result != VK_SUCCESS) + { + mesa_logd("wsi: failed to create memory for dma-buf sync import/export test."); + goto out; + } + + int fd; + struct VkMemoryGetFdInfoKHR get_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, + .memory = mem, + .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + result = wsi->GetMemoryFdKHR(device, &get_info, &fd); + if (result != VK_SUCCESS) + { + mesa_logd("wsi: failed to dma-buf fd for sync import/export test."); + goto free_mem; + } + + int sync_file; + result = wsi_dma_buf_export_sync_file(fd, &sync_file); + if (result != VK_SUCCESS) + { + mesa_logd("wsi: failed export sync file from dma-buf fd."); + goto free_fd; + } + + result = wsi_dma_buf_import_sync_file(fd, sync_file); + if (result != VK_SUCCESS) + { + mesa_logd("wsi: failed import sync file to dma-buf fd."); + goto free_sync_file; + } + + mesa_logd("Found support for dma-buf sync import/export"); + +free_sync_file: + close(sync_file); +free_fd: + close(fd); +free_mem: + wsi->FreeMemory(device, mem, NULL); +out: + /* We can ignore const here -- this field is managed entirely by this + * function, in an atomic manner. + */ + p_atomic_set(&((struct wsi_device *)wsi)->cached_sync_file_import_export_result, result - 1); + return result; +} + static VkResult prepare_signal_dma_buf_from_semaphore(struct wsi_swapchain *chain, const struct wsi_image *image) diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h index d523202fcda..2bc24435d84 100644 --- a/src/vulkan/wsi/wsi_common_private.h +++ b/src/vulkan/wsi/wsi_common_private.h @@ -408,6 +408,7 @@ wsi_drm_wait_for_explicit_sync_release(struct wsi_swapchain *chain, struct wsi_image **images, uint64_t rel_timeout_ns, uint32_t *image_index); + #endif struct wsi_interface {