From 5181f4067001cfadb3a6b3d23527f4099013ebe3 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 29 Apr 2021 11:31:25 -0700 Subject: [PATCH] freedreno/drm: Allow FD_BO_PREP_FLUSH without _NOSYNC This provides the upper layer (gallium, etc) a way to ensure that rendering involving the bo has been flushed all the way to the kernel. Signed-off-by: Rob Clark Part-of: --- src/freedreno/drm/freedreno_bo.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/freedreno/drm/freedreno_bo.c b/src/freedreno/drm/freedreno_bo.c index dbffaffa01d..7be0c7839a0 100644 --- a/src/freedreno/drm/freedreno_bo.c +++ b/src/freedreno/drm/freedreno_bo.c @@ -453,21 +453,24 @@ fd_bo_map(struct fd_bo *bo) int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op) { - if (op & FD_BO_PREP_NOSYNC) { + if (op & (FD_BO_PREP_NOSYNC | FD_BO_PREP_FLUSH)) { simple_mtx_lock(&table_lock); enum fd_bo_state state = fd_bo_state(bo); simple_mtx_unlock(&table_lock); - switch (state) { - case FD_BO_STATE_IDLE: + if (state == FD_BO_STATE_IDLE) return 0; - case FD_BO_STATE_BUSY: - if (op & FD_BO_PREP_FLUSH) - bo_flush(bo); + + if (op & FD_BO_PREP_FLUSH) + bo_flush(bo); + + /* If we have *only* been asked to flush, then we aren't really + * interested about whether shared buffers are busy, so avoid + * the kernel ioctl. + */ + if ((state == FD_BO_STATE_BUSY) || + (op == FD_BO_PREP_FLUSH)) return -EBUSY; - case FD_BO_STATE_UNKNOWN: - break; - } } /* In case the bo is referenced by a deferred submit, flush up to the @@ -475,7 +478,10 @@ fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op) */ bo_flush(bo); - return bo->funcs->cpu_prep(bo, pipe, op); + /* FD_BO_PREP_FLUSH is purely a frontend flag, and is not seen/handled + * by backend or kernel: + */ + return bo->funcs->cpu_prep(bo, pipe, op & ~FD_BO_PREP_FLUSH); } void