swr: Use the default behavior of ALLOW_MAPPED_BUFFERS.
[mesa.git] / src / gallium / drivers / v3d / v3d_fence.c
index 54bce56240357fe1251ffd58df16eeb502b52b90..d4b4e48c46f6546b791c4b67bfc41eb1db7be234 100644 (file)
@@ -21,7 +21,7 @@
  * IN THE SOFTWARE.
  */
 
-/** @file vc5_fence.c
+/** @file v3d_fence.c
  *
  * Seqno-based fence management.
  *
  */
 
 #include "util/u_inlines.h"
+#include "util/os_time.h"
 
 #include "v3d_context.h"
 #include "v3d_bufmgr.h"
 
-struct vc5_fence {
+struct v3d_fence {
         struct pipe_reference reference;
-        uint32_t sync;
+        int fd;
 };
 
 static void
-vc5_fence_reference(struct pipe_screen *pscreen,
+v3d_fence_reference(struct pipe_screen *pscreen,
                     struct pipe_fence_handle **pp,
                     struct pipe_fence_handle *pf)
 {
-        struct vc5_screen *screen = vc5_screen(pscreen);
-        struct vc5_fence **p = (struct vc5_fence **)pp;
-        struct vc5_fence *f = (struct vc5_fence *)pf;
-        struct vc5_fence *old = *p;
+        struct v3d_fence **p = (struct v3d_fence **)pp;
+        struct v3d_fence *f = (struct v3d_fence *)pf;
+        struct v3d_fence *old = *p;
 
         if (pipe_reference(&(*p)->reference, &f->reference)) {
-                drmSyncobjDestroy(screen->fd, old->sync);
+                close(old->fd);
                 free(old);
         }
         *p = f;
 }
 
-static boolean
-vc5_fence_finish(struct pipe_screen *pscreen,
+static bool
+v3d_fence_finish(struct pipe_screen *pscreen,
                 struct pipe_context *ctx,
                  struct pipe_fence_handle *pf,
                  uint64_t timeout_ns)
 {
-        struct vc5_screen *screen = vc5_screen(pscreen);
-        struct vc5_fence *f = (struct vc5_fence *)pf;
+        struct v3d_screen *screen = v3d_screen(pscreen);
+        struct v3d_fence *f = (struct v3d_fence *)pf;
+        int ret;
 
-        return drmSyncobjWait(screen->fd, &f->sync, 1, timeout_ns, 0, NULL);
+        unsigned syncobj;
+        ret = drmSyncobjCreate(screen->fd, 0, &syncobj);
+        if (ret) {
+                fprintf(stderr, "Failed to create syncobj to wait on: %d\n",
+                        ret);
+                return false;
+        }
+
+        ret = drmSyncobjImportSyncFile(screen->fd, syncobj, f->fd);
+        if (ret) {
+                fprintf(stderr, "Failed to import fence to syncobj: %d\n", ret);
+                return false;
+        }
+
+        uint64_t abs_timeout = os_time_get_absolute_timeout(timeout_ns);
+        if (abs_timeout == OS_TIMEOUT_INFINITE)
+                abs_timeout = INT64_MAX;
+
+        ret = drmSyncobjWait(screen->fd, &syncobj, 1, abs_timeout, 0, NULL);
+
+        drmSyncobjDestroy(screen->fd, syncobj);
+
+        return ret >= 0;
 }
 
-struct vc5_fence *
-vc5_fence_create(struct vc5_context *vc5)
+struct v3d_fence *
+v3d_fence_create(struct v3d_context *v3d)
 {
-        struct vc5_fence *f = calloc(1, sizeof(*f));
+        struct v3d_fence *f = calloc(1, sizeof(*f));
         if (!f)
                 return NULL;
 
-        uint32_t new_sync;
-        /* Make a new sync object for the context. */
-        int ret = drmSyncobjCreate(vc5->fd, DRM_SYNCOBJ_CREATE_SIGNALED,
-                                   &new_sync);
-        if (ret) {
+        /* Snapshot the last V3D rendering's out fence.  We'd rather have
+         * another syncobj instead of a sync file, but this is all we get.
+         * (HandleToFD/FDToHandle just gives you another syncobj ID for the
+         * same syncobj).
+         */
+        drmSyncobjExportSyncFile(v3d->fd, v3d->out_sync, &f->fd);
+        if (f->fd == -1) {
+                fprintf(stderr, "export failed\n");
                 free(f);
                 return NULL;
         }
 
         pipe_reference_init(&f->reference, 1);
-        f->sync = vc5->out_sync;
-        vc5->out_sync = new_sync;
 
         return f;
 }
 
 void
-vc5_fence_init(struct vc5_screen *screen)
+v3d_fence_init(struct v3d_screen *screen)
 {
-        screen->base.fence_reference = vc5_fence_reference;
-        screen->base.fence_finish = vc5_fence_finish;
+        screen->base.fence_reference = v3d_fence_reference;
+        screen->base.fence_finish = v3d_fence_finish;
 }