asahi: Support importing sync objects on BO export
authorAsahi Lina <lina@asahilina.net>
Fri, 3 Mar 2023 09:55:24 +0000 (18:55 +0900)
committerMarge Bot <emma+marge@anholt.net>
Thu, 16 Mar 2023 20:42:01 +0000 (20:42 +0000)
When a BO is exported, implicit sync convention requires that writers
signal a fence on the object when complete. We already do this for BOs
that are *already* exported, but it is possible for a BO to be written
to, then exported for the first time.

Add a field to agx_bo to keep track of the current writer syncobj
handle. On first export, we use this to import it into the DMA-BUF.

Signed-off-by: Asahi Lina <lina@asahilina.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21620>

src/asahi/lib/agx_bo.h
src/asahi/lib/agx_device.c

index e749e4d..f39a2aa 100644 (file)
@@ -98,6 +98,9 @@ struct agx_bo {
    /* DMA-BUF fd clone for adding fences to imports/exports */
    int prime_fd;
 
+   /* Syncobj handle of the current writer, if any */
+   int writer_syncobj;
+
    /* Globally unique value (system wide) for tracing. Exists for resources,
     * command buffers, GPU submissions, segments, segmentent lists, encoders,
     * accelerators, and channels. Corresponds to Instruments' magic table
index bd3e343..c5f9536 100644 (file)
@@ -239,11 +239,28 @@ agx_bo_export(struct agx_bo *bo)
    if (drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC, &fd))
       return -1;
 
-   bo->flags |= AGX_BO_SHARED;
-   if (bo->prime_fd == -1)
+   if (!(bo->flags & AGX_BO_SHARED)) {
+      bo->flags |= AGX_BO_SHARED;
+      assert(bo->prime_fd == -1);
       bo->prime_fd = dup(fd);
-   assert(bo->prime_fd >= 0);
 
+      /* If there is a pending writer to this BO, import it into the buffer
+       * for implicit sync.
+       */
+      if (bo->writer_syncobj) {
+         int out_sync_fd = -1;
+         int ret = drmSyncobjExportSyncFile(bo->dev->fd, bo->writer_syncobj,
+                                            &out_sync_fd);
+         assert(ret >= 0);
+         assert(out_sync_fd >= 0);
+
+         ret = agx_import_sync_file(bo->dev, bo, out_sync_fd);
+         assert(ret >= 0);
+         close(out_sync_fd);
+      }
+   }
+
+   assert(bo->prime_fd >= 0);
    return fd;
 }