Mesa (master): iris: Fix export of fences that have already completed.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jan 15 22:48:17 UTC 2020


Module: Mesa
Branch: master
Commit: e9f9a944d3497f892ec92994197c9442ac9ee324
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e9f9a944d3497f892ec92994197c9442ac9ee324

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Thu Dec 19 13:51:07 2019 -0800

iris: Fix export of fences that have already completed.

After flushing batches, iris_fence_flush() asks the kernel whether
each batch's last_syncpt has already signalled or not.  (The idea is
that either the compute or render batch may not have actually had any
work queued up, so last_syncpt there might have been signalled a long
time ago.)  If it's already completed, we don't bother to record it.

A strange corner is the case of repeated flushes.  For example, we
might flush for some reason, and hit a glFlush(), and hit SwapBuffers.
It's possible for all the batches to have been flushed previously, -and-
for them to have actually completed.  In this case, we'll see that there
are no syncobj's to wait on, and record fence->count == 0.

This works fine internally - fence_finish can see count == 0 and realize
that it doesn't need to wait, for example.  But when working with native
FDs, we may be asked to export a fence with count == 0.  So we need an
actual synchronization primitive we can hand off.  Because all of the
relevant batches had been signalled when creating the fence, we want the
new dummy fence to be signalled as well.

So we just make a signalled syncobj and export it.

Reviewed-by: Kristian H. Kristensen <hoegsberg at google.com>

---

 src/gallium/drivers/iris/iris_fence.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/gallium/drivers/iris/iris_fence.c b/src/gallium/drivers/iris/iris_fence.c
index 2225774a601..3de906cca29 100644
--- a/src/gallium/drivers/iris/iris_fence.c
+++ b/src/gallium/drivers/iris/iris_fence.c
@@ -300,6 +300,22 @@ iris_fence_get_fd(struct pipe_screen *p_screen,
    struct iris_screen *screen = (struct iris_screen *)p_screen;
    int fd = -1;
 
+   if (fence->count == 0) {
+      /* Our fence has no syncobj's recorded.  This means that all of the
+       * batches had already completed, their syncobj's had been signalled,
+       * and so we didn't bother to record them.  But we're being asked to
+       * export such a fence.  So export a dummy already-signalled syncobj.
+       */
+      struct drm_syncobj_handle args = {
+         .flags = DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE, .fd = -1,
+      };
+
+      args.handle = gem_syncobj_create(screen->fd, DRM_SYNCOBJ_CREATE_SIGNALED);
+      gen_ioctl(screen->fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &args);
+      gem_syncobj_destroy(screen->fd, args.handle);
+      return args.fd;
+   }
+
    for (unsigned i = 0; i < fence->count; i++) {
       struct drm_syncobj_handle args = {
          .handle = fence->syncpt[i]->handle,



More information about the mesa-commit mailing list