v3d: Implemented some functions to support eglWaitsync.
authorJoonbum Ko <joonbum.ko@samsung.com>
Tue, 2 Jun 2020 04:47:22 +0000 (13:47 +0900)
committerXuelian Bai <xuelian.bai@samsung.com>
Tue, 21 Feb 2023 06:32:49 +0000 (14:32 +0800)
 This is a test phase and can be fixed later.

Change-Id: I9670fc27b331b7ac4ccbcb9f659d82f4ab78f058
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/gallium/drivers/v3d/v3d_context.c
src/gallium/drivers/v3d/v3d_context.h
src/gallium/drivers/v3d/v3d_fence.c
src/gallium/drivers/v3d/v3d_job.c

index 9a816e9..edcfc9a 100644 (file)
@@ -368,6 +368,9 @@ v3d_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
 
         v3d->fd = screen->fd;
 
+        if(v3d_fence_context_init(v3d))
+                goto fail;
+
         slab_create_child(&v3d->transfer_pool, &screen->transfer_pool);
 
         v3d->uploader = u_upload_create_default(&v3d->base);
index 9cf83cb..a5c3bab 100644 (file)
@@ -616,6 +616,9 @@ struct v3d_context {
         struct v3d_perfmon_state *active_perfmon;
         struct v3d_perfmon_state *last_perfmon;
         /** @} */
+
+        int in_fence_fd;
+        uint32_t in_syncobj;
 };
 
 struct v3d_rasterizer_state {
@@ -806,6 +809,9 @@ void v3d_get_tile_buffer_size(bool is_msaa,
                               uint32_t *tile_width,
                               uint32_t *tile_height,
                               uint32_t *max_bpp);
+int v3d_fence_context_init(struct v3d_context *v3d);
+
+void v3d_tf_update_counters(struct v3d_context *v3d);
 
 #ifdef ENABLE_SHADER_CACHE
 struct v3d_compiled_shader *v3d_disk_cache_retrieve(struct v3d_context *v3d,
index ca0a145..ed7381b 100644 (file)
@@ -34,6 +34,7 @@
  * fired off as our fence marker.
  */
 
+#include <libsync.h>
 #include <fcntl.h>
 
 #include "util/u_inlines.h"
@@ -142,6 +143,34 @@ v3d_fence_create(struct v3d_context *v3d)
         return f;
 }
 
+static void
+v3d_fence_create_fd(struct pipe_context *pctx, struct pipe_fence_handle **pf,
+                    int fd, enum pipe_fd_type type)
+{
+        struct v3d_fence **fence = (struct v3d_fence **)pf;
+        struct v3d_fence *f = calloc(1, sizeof(*f));
+
+        assert(type == PIPE_FD_TYPE_NATIVE_SYNC);
+
+        if (f) {
+                pipe_reference_init(&f->reference, 1);
+                f->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+        }
+
+        *fence = f;
+}
+
+static void
+v3d_fence_server_sync(struct pipe_context *pctx,
+                      struct pipe_fence_handle *pfence)
+{
+        struct v3d_context *v3d = (struct v3d_context *)pctx;
+        struct v3d_fence *fence = (struct v3d_fence *)pfence;
+
+        if (fence->fd >= 0)
+                sync_accumulate("v3d", &v3d->in_fence_fd, fence->fd);
+}
+
 static int
 v3d_fence_get_fd(struct pipe_screen *screen, struct pipe_fence_handle *pfence)
 {
@@ -150,6 +179,24 @@ v3d_fence_get_fd(struct pipe_screen *screen, struct pipe_fence_handle *pfence)
         return fcntl(fence->fd, F_DUPFD_CLOEXEC, 3);
 }
 
+int
+v3d_fence_context_init(struct v3d_context *v3d)
+{
+        v3d->base.create_fence_fd = v3d_fence_create_fd;
+        v3d->base.fence_server_sync = v3d_fence_server_sync;
+        v3d->in_fence_fd = -1;
+
+        /* Since we initialize the in_fence_fd to -1 (no wait necessary),
+         * we also need to initialize our in_syncobj as signaled.
+         */
+        if (v3d->screen->has_syncobj) {
+                return drmSyncobjCreate(v3d->fd, DRM_SYNCOBJ_CREATE_SIGNALED,
+                                        &v3d->in_syncobj);
+        } else {
+                return 0;
+        }
+}
+
 void
 v3d_fence_init(struct v3d_screen *screen)
 {
index b61d1c9..e1c361f 100644 (file)
@@ -511,7 +511,19 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
          * finished, we also need to block on any previous TFU job we may have
          * dispatched.
          */
-        job->submit.in_sync_rcl = v3d->out_sync;
+
+        if (screen->has_syncobj) {
+                if (v3d->in_fence_fd >= 0) {
+                         /* This replaces the fence in the syncobj. */
+                        drmSyncobjImportSyncFile(v3d->fd, v3d->in_syncobj,
+                                                 v3d->in_fence_fd);
+                        job->submit.in_sync_rcl = v3d->in_syncobj;
+                        close(v3d->in_fence_fd);
+                        v3d->in_fence_fd = -1;
+                }
+        } else {
+                job->submit.in_sync_rcl = v3d->out_sync;
+        }
 
         /* Update the sync object for the last rendering by our context. */
         job->submit.out_sync = v3d->out_sync;