From e9eb44b45b8d4a2f06ef83365b28eca55c0f3fb4 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 15 Aug 2016 13:26:18 -0400 Subject: freedreno: add fence fd support Signed-off-by: Rob Clark --- freedreno/freedreno_drmif.h | 1 + freedreno/freedreno_priv.h | 3 ++- freedreno/freedreno_ringbuffer.c | 11 ++++++++--- freedreno/freedreno_ringbuffer.h | 5 +++++ freedreno/kgsl/kgsl_ringbuffer.c | 6 +++++- freedreno/msm/msm_ringbuffer.c | 16 +++++++++++++++- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h index 2d913e6c..7a8073ff 100644 --- a/freedreno/freedreno_drmif.h +++ b/freedreno/freedreno_drmif.h @@ -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); diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h index cdfdbe8d..86da83b9 100644 --- a/freedreno/freedreno_priv.h +++ b/freedreno/freedreno_priv.h @@ -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, diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c index 22dafb39..c132145a 100644 --- a/freedreno/freedreno_ringbuffer.c +++ b/freedreno/freedreno_ringbuffer.c @@ -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); } diff --git a/freedreno/freedreno_ringbuffer.h b/freedreno/freedreno_ringbuffer.h index 8899b5de..108d5a6d 100644 --- a/freedreno/freedreno_ringbuffer.h +++ b/freedreno/freedreno_ringbuffer.h @@ -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); diff --git a/freedreno/kgsl/kgsl_ringbuffer.c b/freedreno/kgsl/kgsl_ringbuffer.c index 7b3298ab..e4696b1b 100644 --- a/freedreno/kgsl/kgsl_ringbuffer.c +++ b/freedreno/kgsl/kgsl_ringbuffer.c @@ -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: */ diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c index 60f03154..5117df1a 100644 --- a/freedreno/msm/msm_ringbuffer.c +++ b/freedreno/msm/msm_ringbuffer.c @@ -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); -- cgit v1.2.3