diff --git a/src/freedreno/drm/freedreno_bo.c b/src/freedreno/drm/freedreno_bo.c index 5229eaf17aa..d45f30dfa3c 100644 --- a/src/freedreno/drm/freedreno_bo.c +++ b/src/freedreno/drm/freedreno_bo.c @@ -372,7 +372,7 @@ fd_bo_fini_common(struct fd_bo *bo) VG_BO_FREE(bo); for (int i = 0; i < bo->nr_fences; i++) - fd_pipe_del(bo->fences[i].pipe); + fd_fence_del(bo->fences[i]); if (bo->fences != &bo->_inline_fence) free(bo->fences); @@ -420,9 +420,16 @@ close_handles(struct fd_device *dev, uint32_t *handles, unsigned cnt) static void bo_flush(struct fd_bo *bo) { - for (int i = 0; i < bo->nr_fences; i++) { - struct fd_bo_fence *f = &bo->fences[i]; - fd_pipe_flush(f->pipe, f->fence); + simple_mtx_lock(&fence_lock); + unsigned nr = bo->nr_fences; + struct fd_fence *fences[nr]; + for (unsigned i = 0; i < nr; i++) + fences[i] = fd_fence_ref_locked(bo->fences[i]); + simple_mtx_unlock(&fence_lock); + + for (unsigned i = 0; i < nr; i++) { + fd_fence_flush(bo->fences[i]); + fd_fence_del(fences[i]); } } @@ -598,13 +605,11 @@ cleanup_fences(struct fd_bo *bo) simple_mtx_assert_locked(&fence_lock); for (int i = 0; i < bo->nr_fences; i++) { - struct fd_bo_fence *f = &bo->fences[i]; + struct fd_fence *f = bo->fences[i]; - if (fd_fence_before(f->pipe->control->fence, f->fence)) + if (fd_fence_before(f->pipe->control->fence, f->ufence)) continue; - struct fd_pipe *pipe = f->pipe; - bo->nr_fences--; if (bo->nr_fences > 0) { @@ -613,12 +618,12 @@ cleanup_fences(struct fd_bo *bo) i--; } - fd_pipe_del_locked(pipe); + fd_fence_del_locked(f); } } void -fd_bo_add_fence(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t fence) +fd_bo_add_fence(struct fd_bo *bo, struct fd_fence *fence) { simple_mtx_assert_locked(&fence_lock); @@ -626,13 +631,16 @@ fd_bo_add_fence(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t fence) return; /* The common case is bo re-used on the same pipe it had previously - * been used on: + * been used on, so just replace the previous fence. */ for (int i = 0; i < bo->nr_fences; i++) { - struct fd_bo_fence *f = &bo->fences[i]; - if (f->pipe == pipe) { - assert(fd_fence_before(f->fence, fence)); - f->fence = fence; + struct fd_fence *f = bo->fences[i]; + if (f == fence) + return; + if (f->pipe == fence->pipe) { + assert(fd_fence_before(f->ufence, fence->ufence)); + fd_fence_del_locked(f); + bo->fences[i] = fd_fence_ref_locked(fence); return; } } @@ -650,10 +658,7 @@ fd_bo_add_fence(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t fence) APPEND(bo, fences, bo->_inline_fence); } - APPEND(bo, fences, (struct fd_bo_fence){ - .pipe = fd_pipe_ref_locked(pipe), - .fence = fence, - }); + APPEND(bo, fences, fd_fence_ref_locked(fence)); } enum fd_bo_state diff --git a/src/freedreno/drm/freedreno_drmif.h b/src/freedreno/drm/freedreno_drmif.h index 7c14d93ab61..d88fd510318 100644 --- a/src/freedreno/drm/freedreno_drmif.h +++ b/src/freedreno/drm/freedreno_drmif.h @@ -208,15 +208,6 @@ int fd_pipe_wait_timeout(struct fd_pipe *pipe, const struct fd_fence *fence, /* buffer-object functions: */ -struct fd_bo_fence { - /* For non-shared buffers, track the last pipe the buffer was active - * on, and the per-pipe fence value that indicates when the buffer is - * idle: - */ - uint32_t fence; - struct fd_pipe *pipe; -}; - struct fd_bo { struct fd_device *dev; uint32_t size; @@ -244,13 +235,13 @@ struct fd_bo { time_t free_time; /* time when added to bucket-list */ unsigned short nr_fences, max_fences; - struct fd_bo_fence *fences; + struct fd_fence **fences; /* In the common case, there is no more than one fence attached. * This provides storage for the fences table until it grows to * be larger than a single element. */ - struct fd_bo_fence _inline_fence; + struct fd_fence *_inline_fence; }; struct fd_bo *_fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags); diff --git a/src/freedreno/drm/freedreno_priv.h b/src/freedreno/drm/freedreno_priv.h index 4772743064e..b166b0b8735 100644 --- a/src/freedreno/drm/freedreno_priv.h +++ b/src/freedreno/drm/freedreno_priv.h @@ -342,7 +342,7 @@ struct fd_bo_funcs { bool (*prefer_upload)(struct fd_bo *bo, unsigned len); }; -void fd_bo_add_fence(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t fence); +void fd_bo_add_fence(struct fd_bo *bo, struct fd_fence *fence); enum fd_bo_state { FD_BO_STATE_IDLE, diff --git a/src/freedreno/drm/freedreno_ringbuffer_sp.c b/src/freedreno/drm/freedreno_ringbuffer_sp.c index f78ff44fb44..a6dd3ed03cb 100644 --- a/src/freedreno/drm/freedreno_ringbuffer_sp.c +++ b/src/freedreno/drm/freedreno_ringbuffer_sp.c @@ -179,9 +179,11 @@ fd_submit_sp_flush_prep(struct fd_submit *submit, int in_fence_fd, for (unsigned i = 0; i < primary->u.nr_cmds; i++) fd_submit_append_bo(fd_submit, primary->u.cmds[i].ring_bo); + out_fence->ufence = submit->fence; + simple_mtx_lock(&fence_lock); for (unsigned i = 0; i < fd_submit->nr_bos; i++) { - fd_bo_add_fence(fd_submit->bos[i], submit->pipe, submit->fence); + fd_bo_add_fence(fd_submit->bos[i], out_fence); has_shared |= fd_submit->bos[i]->alloc_flags & FD_BO_SHARED; } simple_mtx_unlock(&fence_lock); diff --git a/src/freedreno/drm/msm/msm_ringbuffer.c b/src/freedreno/drm/msm/msm_ringbuffer.c index dd9cb0c0f79..3bfcce55dd7 100644 --- a/src/freedreno/drm/msm/msm_ringbuffer.c +++ b/src/freedreno/drm/msm/msm_ringbuffer.c @@ -345,7 +345,7 @@ msm_submit_flush(struct fd_submit *submit, int in_fence_fd, bool use_fence_fd) simple_mtx_lock(&fence_lock); for (unsigned j = 0; j < msm_submit->nr_bos; j++) { - fd_bo_add_fence(msm_submit->bos[j], submit->pipe, submit->fence); + fd_bo_add_fence(msm_submit->bos[j], out_fence); } simple_mtx_unlock(&fence_lock); diff --git a/src/freedreno/drm/msm/msm_ringbuffer_sp.c b/src/freedreno/drm/msm/msm_ringbuffer_sp.c index 2403837b5bb..55639d80661 100644 --- a/src/freedreno/drm/msm/msm_ringbuffer_sp.c +++ b/src/freedreno/drm/msm/msm_ringbuffer_sp.c @@ -152,7 +152,6 @@ flush_submit_list(struct list_head *submit_list) msm_dump_submit(&req); } else if (!ret) { fd_submit->out_fence->kfence = req.fence; - fd_submit->out_fence->ufence = fd_submit->base.fence; fd_submit->out_fence->fence_fd = req.fence_fd; } diff --git a/src/freedreno/drm/virtio/virtio_ringbuffer.c b/src/freedreno/drm/virtio/virtio_ringbuffer.c index 42cee1df270..c4e1b4d7a67 100644 --- a/src/freedreno/drm/virtio/virtio_ringbuffer.c +++ b/src/freedreno/drm/virtio/virtio_ringbuffer.c @@ -176,7 +176,6 @@ flush_submit_list(struct list_head *submit_list) struct fd_fence *out_fence = fd_submit->out_fence; out_fence->kfence = kfence; - out_fence->ufence = fd_submit->base.fence; /* Even if gallium driver hasn't requested a fence-fd, request one. * This way, if we have to block waiting for the fence, we can do