OSDN Git Service

freedreno: add fence fd support
authorRob Clark <robclark@freedesktop.org>
Mon, 15 Aug 2016 17:26:18 +0000 (13:26 -0400)
committerRob Clark <robclark@freedesktop.org>
Sat, 5 Nov 2016 14:18:44 +0000 (10:18 -0400)
Signed-off-by: Rob Clark <robclark@freedesktop.org>
freedreno/freedreno_drmif.h
freedreno/freedreno_priv.h
freedreno/freedreno_ringbuffer.c
freedreno/freedreno_ringbuffer.h
freedreno/kgsl/kgsl_ringbuffer.c
freedreno/msm/msm_ringbuffer.c

index 2d913e6..7a8073f 100644 (file)
@@ -92,6 +92,7 @@ int fd_device_fd(struct fd_device *dev);
 enum fd_version {
        FD_VERSION_MADVISE = 1,            /* kernel supports madvise */
        FD_VERSION_UNLIMITED_CMDS = 1,     /* submits w/ >4 cmd buffers (growable ringbuffer) */
+       FD_VERSION_FENCE_FD = 2,           /* submit command supports in/out fences */
 };
 enum fd_version fd_device_version(struct fd_device *dev);
 
index cdfdbe8..86da83b 100644 (file)
@@ -133,7 +133,8 @@ struct fd_ringmarker {
 
 struct fd_ringbuffer_funcs {
        void * (*hostptr)(struct fd_ringbuffer *ring);
-       int (*flush)(struct fd_ringbuffer *ring, uint32_t *last_start);
+       int (*flush)(struct fd_ringbuffer *ring, uint32_t *last_start,
+                       int in_fence_fd, int *out_fence_fd);
        void (*grow)(struct fd_ringbuffer *ring, uint32_t size);
        void (*reset)(struct fd_ringbuffer *ring);
        void (*emit_reloc)(struct fd_ringbuffer *ring,
index 22dafb3..c132145 100644 (file)
@@ -80,10 +80,15 @@ void fd_ringbuffer_reset(struct fd_ringbuffer *ring)
                ring->funcs->reset(ring);
 }
 
-/* maybe get rid of this and use fd_ringmarker_flush() from DDX too? */
 int fd_ringbuffer_flush(struct fd_ringbuffer *ring)
 {
-       return ring->funcs->flush(ring, ring->last_start);
+       return ring->funcs->flush(ring, ring->last_start, -1, NULL);
+}
+
+int fd_ringbuffer_flush2(struct fd_ringbuffer *ring, int in_fence_fd,
+               int *out_fence_fd)
+{
+       return ring->funcs->flush(ring, ring->last_start, in_fence_fd, out_fence_fd);
 }
 
 void fd_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t ndwords)
@@ -177,5 +182,5 @@ uint32_t fd_ringmarker_dwords(struct fd_ringmarker *start,
 int fd_ringmarker_flush(struct fd_ringmarker *marker)
 {
        struct fd_ringbuffer *ring = marker->ring;
-       return ring->funcs->flush(ring, marker->cur);
+       return ring->funcs->flush(ring, marker->cur, -1, NULL);
 }
index 8899b5d..108d5a6 100644 (file)
@@ -56,6 +56,11 @@ void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
                struct fd_ringbuffer *parent);
 void fd_ringbuffer_reset(struct fd_ringbuffer *ring);
 int fd_ringbuffer_flush(struct fd_ringbuffer *ring);
+/* in_fence_fd: -1 for no in-fence, else fence fd
+ * out_fence_fd: NULL for no output-fence requested, else ptr to return out-fence
+ */
+int fd_ringbuffer_flush2(struct fd_ringbuffer *ring, int in_fence_fd,
+               int *out_fence_fd);
 void fd_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t ndwords);
 uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring);
 
index 7b3298a..e4696b1 100644 (file)
@@ -113,7 +113,8 @@ static void * kgsl_ringbuffer_hostptr(struct fd_ringbuffer *ring)
        return kgsl_ring->bo->hostptr;
 }
 
-static int kgsl_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start)
+static int kgsl_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start,
+               int in_fence_fd, int *out_fence_fd)
 {
        struct kgsl_ringbuffer *kgsl_ring = to_kgsl_ringbuffer(ring);
        struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(ring->pipe);
@@ -131,6 +132,9 @@ static int kgsl_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_star
        };
        int ret;
 
+       assert(in_fence_fd == -1);
+       assert(out_fence_fd == NULL);
+
        kgsl_pipe_pre_submit(kgsl_pipe);
 
        /* z180_cmdstream_issueibcmds() is made of fail: */
index 60f0315..5117df1 100644 (file)
@@ -395,7 +395,8 @@ static void dump_submit(struct msm_ringbuffer *msm_ring)
        }
 }
 
-static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start)
+static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start,
+               int in_fence_fd, int *out_fence_fd)
 {
        struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
        struct drm_msm_gem_submit req = {
@@ -404,6 +405,15 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
        uint32_t i;
        int ret;
 
+       if (in_fence_fd != -1) {
+               req.flags |= MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_NO_IMPLICIT;
+               req.fence_fd = in_fence_fd;
+       }
+
+       if (out_fence_fd) {
+               req.flags |= MSM_SUBMIT_FENCE_FD_OUT;
+       }
+
        finalize_current_cmd(ring, last_start);
 
        /* needs to be after get_cmd() as that could create bos/cmds table: */
@@ -435,6 +445,10 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
                        struct msm_cmd *msm_cmd = msm_ring->cmds[i];
                        msm_cmd->ring->last_timestamp = req.fence;
                }
+
+               if (out_fence_fd) {
+                       *out_fence_fd = req.fence_fd;
+               }
        }
 
        flush_reset(ring);