iris: Add functions to import and export implicit sync state
authorPaulo Zanoni <paulo.r.zanoni@intel.com>
Tue, 31 Jan 2023 21:54:22 +0000 (13:54 -0800)
committerMarge Bot <emma+marge@anholt.net>
Fri, 2 Jun 2023 20:46:48 +0000 (20:46 +0000)
Xe KMD is not going to support implicit synchronization, so we need to
use extra ioctls to import/export implicit synchronization state from
gem BOs from/to drm syncobjs.

Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22544>

src/gallium/drivers/iris/iris_batch.c
src/gallium/drivers/iris/iris_batch.h
src/gallium/drivers/iris/iris_bufmgr.c
src/gallium/drivers/iris/iris_bufmgr.h

index b66f990..d9ddedd 100644 (file)
@@ -815,6 +815,36 @@ iris_batch_update_syncobjs(struct iris_batch *batch)
    }
 }
 
+/**
+ * Convert the syncobj which will be signaled when this batch completes
+ * to a SYNC_FILE object, for use with import/export sync ioctls.
+ */
+bool
+iris_batch_syncobj_to_sync_file_fd(struct iris_batch *batch, int *out_fd)
+{
+   int drm_fd = batch->screen->fd;
+
+   struct iris_syncobj *batch_syncobj =
+      iris_batch_get_signal_syncobj(batch);
+
+   struct drm_syncobj_handle syncobj_to_fd_ioctl = {
+      .handle = batch_syncobj->handle,
+      .flags = DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE,
+      .fd = -1,
+   };
+   if (intel_ioctl(drm_fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD,
+                   &syncobj_to_fd_ioctl)) {
+      fprintf(stderr, "DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD ioctl failed (%d)\n",
+              errno);
+      return false;
+   }
+
+   assert(syncobj_to_fd_ioctl.fd >= 0);
+   *out_fd = syncobj_to_fd_ioctl.fd;
+
+   return true;
+}
+
 const char *
 iris_batch_name_to_string(enum iris_batch_name name)
 {
index dcafe53..05cb19e 100644 (file)
@@ -233,6 +233,8 @@ void iris_use_pinned_bo(struct iris_batch *batch, struct iris_bo *bo,
 
 enum pipe_reset_status iris_batch_check_for_reset(struct iris_batch *batch);
 
+bool iris_batch_syncobj_to_sync_file_fd(struct iris_batch *batch, int *out_fd);
+
 static inline unsigned
 iris_batch_bytes_used(struct iris_batch *batch)
 {
index 27a4224..dbe8685 100644 (file)
@@ -53,6 +53,7 @@
 #include "dev/intel_debug.h"
 #include "common/intel_gem.h"
 #include "dev/intel_device_info.h"
+#include "drm-uapi/dma-buf.h"
 #include "isl/isl.h"
 #include "util/os_mman.h"
 #include "util/u_debug.h"
@@ -442,6 +443,68 @@ vma_free(struct iris_bufmgr *bufmgr,
    util_vma_heap_free(&bufmgr->vma_allocator[memzone], address, size);
 }
 
+/* Exports a BO's implicit synchronization state to a drm_syncobj, returning
+ * its wrapping iris_syncobj. The drm_syncobj is created new and has to be
+ * destroyed by the caller after the execbuf ioctl.
+ */
+struct iris_syncobj *
+iris_bo_export_sync_state(struct iris_bo *bo)
+{
+   struct iris_bufmgr *bufmgr = bo->bufmgr;
+   int drm_fd = iris_bufmgr_get_fd(bufmgr);
+
+   struct iris_syncobj *iris_syncobj = iris_create_syncobj(bufmgr);
+
+   struct dma_buf_export_sync_file export_sync_file_ioctl = {
+      .flags = DMA_BUF_SYNC_RW, /* TODO */
+      .fd = -1,
+   };
+   if (intel_ioctl(bo->real.prime_fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
+                   &export_sync_file_ioctl)) {
+      fprintf(stderr, "DMA_BUF_IOCTL_EXPORT_SYNC_FILE ioctl failed (%d)\n",
+              errno);
+      goto error_export;
+   }
+
+   int sync_file_fd = export_sync_file_ioctl.fd;
+   assert(sync_file_fd >= 0);
+
+   struct drm_syncobj_handle syncobj_import_ioctl = {
+      .handle = iris_syncobj->handle,
+      .flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE,
+      .fd = sync_file_fd,
+   };
+   if (intel_ioctl(drm_fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE,
+                   &syncobj_import_ioctl)) {
+      fprintf(stderr, "DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE ioctl failed (%d)\n",
+              errno);
+   }
+
+   close(sync_file_fd);
+
+   return iris_syncobj;
+error_export:
+   iris_syncobj_destroy(bufmgr, iris_syncobj);
+   return NULL;
+}
+
+/* Import the state of a sync_file_fd (which we should have gotten from
+ * batch_syncobj_to_sync_file_fd) into a BO as its implicit synchronization
+ * state.
+ */
+void
+iris_bo_import_sync_state(struct iris_bo *bo, int sync_file_fd)
+{
+   struct dma_buf_import_sync_file import_sync_file_ioctl = {
+      .flags = DMA_BUF_SYNC_WRITE,
+      .fd = sync_file_fd,
+   };
+   if (intel_ioctl(bo->real.prime_fd, DMA_BUF_IOCTL_IMPORT_SYNC_FILE,
+                   &import_sync_file_ioctl))
+      fprintf(stderr, "DMA_BUF_IOCTL_IMPORT_SYNC_FILE ioctl failed (%d)\n",
+              errno);
+}
+
 /* A timeout of 0 just checks for busyness. */
 static int
 iris_bo_wait_syncobj(struct iris_bo *bo, int64_t timeout_ns)
index 3e6de09..b0db32e 100644 (file)
@@ -584,4 +584,7 @@ enum iris_madvice {
    IRIS_MADVICE_DONT_NEED = 1,
 };
 
+void iris_bo_import_sync_state(struct iris_bo *bo, int sync_file_fd);
+struct iris_syncobj *iris_bo_export_sync_state(struct iris_bo *bo);
+
 #endif /* IRIS_BUFMGR_H */