[Mesa-dev] [PATCH v3 12/12] anv: Add support for the SYNC_FD handle type for fences
Jason Ekstrand
jason at jlekstrand.net
Fri Aug 25 18:54:32 UTC 2017
---
src/intel/vulkan/anv_gem.c | 28 +++++++++++++++++++++
src/intel/vulkan/anv_gem_stubs.c | 13 ++++++++++
src/intel/vulkan/anv_private.h | 4 +++
src/intel/vulkan/anv_queue.c | 53 +++++++++++++++++++++++++++++++---------
4 files changed, 87 insertions(+), 11 deletions(-)
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index 8283117..3994c6b 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -489,6 +489,34 @@ anv_gem_syncobj_fd_to_handle(struct anv_device *device, int fd)
return args.handle;
}
+int
+anv_gem_syncobj_export_sync_file(struct anv_device *device, uint32_t handle)
+{
+ struct drm_syncobj_handle args = {
+ .handle = handle,
+ .flags = DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE,
+ };
+
+ int ret = anv_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &args);
+ if (ret)
+ return -1;
+
+ return args.fd;
+}
+
+int
+anv_gem_syncobj_import_sync_file(struct anv_device *device,
+ uint32_t handle, int fd)
+{
+ struct drm_syncobj_handle args = {
+ .handle = handle,
+ .fd = fd,
+ .flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE,
+ };
+
+ return anv_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &args);
+}
+
void
anv_gem_syncobj_reset(struct anv_device *device, uint32_t handle)
{
diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c
index 36700d7..02527b5 100644
--- a/src/intel/vulkan/anv_gem_stubs.c
+++ b/src/intel/vulkan/anv_gem_stubs.c
@@ -187,6 +187,19 @@ anv_gem_sync_file_merge(struct anv_device *device, int fd1, int fd2)
unreachable("Unused");
}
+int
+anv_gem_syncobj_export_sync_file(struct anv_device *device, uint32_t handle)
+{
+ unreachable("Unused");
+}
+
+int
+anv_gem_syncobj_import_sync_file(struct anv_device *device,
+ uint32_t handle, int fd)
+{
+ unreachable("Unused");
+}
+
uint32_t
anv_gem_syncobj_create(struct anv_device *device, uint32_t flags)
{
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index f9537c2..b30b71f 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -810,6 +810,10 @@ uint32_t anv_gem_syncobj_create(struct anv_device *device, uint32_t flags);
void anv_gem_syncobj_destroy(struct anv_device *device, uint32_t handle);
int anv_gem_syncobj_handle_to_fd(struct anv_device *device, uint32_t handle);
uint32_t anv_gem_syncobj_fd_to_handle(struct anv_device *device, int fd);
+int anv_gem_syncobj_export_sync_file(struct anv_device *device,
+ uint32_t handle);
+int anv_gem_syncobj_import_sync_file(struct anv_device *device,
+ uint32_t handle, int fd);
void anv_gem_syncobj_reset(struct anv_device *device, uint32_t handle);
bool anv_gem_supports_syncobj_wait(int fd);
int anv_gem_syncobj_wait(struct anv_device *device,
diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c
index a954f65..429bac9 100644
--- a/src/intel/vulkan/anv_queue.c
+++ b/src/intel/vulkan/anv_queue.c
@@ -688,11 +688,14 @@ void anv_GetPhysicalDeviceExternalFencePropertiesKHR(
switch (pExternalFenceInfo->handleType) {
case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
+ case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
if (device->has_syncobj_wait) {
pExternalFenceProperties->exportFromImportedHandleTypes =
- VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR;
pExternalFenceProperties->compatibleHandleTypes =
- VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR;
pExternalFenceProperties->externalFenceFeatures =
VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR |
VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR;
@@ -732,22 +735,41 @@ VkResult anv_ImportFenceFdKHR(
if (!new_impl.syncobj)
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
- /* From the Vulkan 1.0.53 spec:
- *
- * "Importing a fence payload from a file descriptor transfers
- * ownership of the file descriptor from the application to the
- * Vulkan implementation. The application must not perform any
- * operations on the file descriptor after a successful import."
- *
- * If the import fails, we leave the file descriptor open.
+ break;
+
+ case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
+ /* Sync files are a bit tricky. Because we want to continue using the
+ * syncobj implementation of WaitForFences, we don't use the sync file
+ * directly but instead import it into a syncobj.
*/
- close(fd);
+ new_impl.type = ANV_FENCE_TYPE_SYNCOBJ;
+
+ new_impl.syncobj = anv_gem_syncobj_create(device, 0);
+ if (!new_impl.syncobj)
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ if (anv_gem_syncobj_import_sync_file(device, new_impl.syncobj, fd)) {
+ anv_gem_syncobj_destroy(device, new_impl.syncobj);
+ return vk_errorf(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR,
+ "syncobj sync file import failed: %m");
+ }
break;
default:
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
}
+ /* From the Vulkan 1.0.53 spec:
+ *
+ * "Importing a fence payload from a file descriptor transfers
+ * ownership of the file descriptor from the application to the
+ * Vulkan implementation. The application must not perform any
+ * operations on the file descriptor after a successful import."
+ *
+ * If the import fails, we leave the file descriptor open.
+ */
+ close(fd);
+
if (pImportFenceFdInfo->flags & VK_FENCE_IMPORT_TEMPORARY_BIT_KHR) {
anv_fence_impl_cleanup(device, &fence->temporary);
fence->temporary = new_impl;
@@ -784,6 +806,15 @@ VkResult anv_GetFenceFdKHR(
break;
}
+ case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR: {
+ int fd = anv_gem_syncobj_export_sync_file(device, impl->syncobj);
+ if (fd < 0)
+ return vk_error(VK_ERROR_TOO_MANY_OBJECTS);
+
+ *pFd = fd;
+ break;
+ }
+
default:
unreachable("Invalid fence export handle type");
}
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list