Mesa (master): freedreno: Fix TC last_fence optimization

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun May 2 16:03:43 UTC 2021


Module: Mesa
Branch: master
Commit: f3d2fade82c168a7ffffa4bd7bf22585c45c711b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f3d2fade82c168a7ffffa4bd7bf22585c45c711b

Author: Rob Clark <robdclark at chromium.org>
Date:   Sat May  1 11:32:10 2021 -0700

freedreno: Fix TC last_fence optimization

Grabbing the fence value in fd_fence_repopulate() without waiting on
fd_submit_fence::ready doesn't work with async flushes, since we are
waiting for the first flush to complete (ie. we don't have the kernel-
side fence value yet).  Just simplify it and make the "repopulated"
fence delagate to the original fence.

Fixes: e9a9ac6f77f ("freedreno/drm: Async submit support")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4726
Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10567>

---

 src/gallium/drivers/freedreno/freedreno_fence.c | 28 ++++++++++++++++---------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_fence.c b/src/gallium/drivers/freedreno/freedreno_fence.c
index 5279efe155a..d85809317dd 100644
--- a/src/gallium/drivers/freedreno/freedreno_fence.c
+++ b/src/gallium/drivers/freedreno/freedreno_fence.c
@@ -59,14 +59,6 @@ fence_flush(struct pipe_context *pctx, struct pipe_fence_handle *fence,
          }
       }
 
-      /* If after the pre-created unflushed fence is flushed, we end up
-       * re-populated to a previous last_fence, then *that* is the one
-       * whose submit_fence.ready we want to wait on:
-       */
-      if (fence->last_fence) {
-         return fence_flush(pctx, fence->last_fence, timeout);
-      }
-
       util_queue_fence_wait(&fence->submit_fence.ready);
 
       /* We've already waited for batch to be flushed and fence->batch
@@ -89,14 +81,15 @@ fence_flush(struct pipe_context *pctx, struct pipe_fence_handle *fence,
 void
 fd_fence_repopulate(struct pipe_fence_handle *fence, struct pipe_fence_handle *last_fence)
 {
+   if (last_fence->last_fence)
+      fd_fence_repopulate(fence, last_fence->last_fence);
+
    /* The fence we are re-populating must not be an fd-fence (but last_fince
     * might have been)
     */
    assert(!fence->submit_fence.use_fence_fd);
    assert(!last_fence->batch);
 
-   fence->submit_fence.fence = last_fence->submit_fence.fence;
-
    fd_fence_ref(&fence->last_fence, last_fence);
 
    /* We have nothing to flush, so nothing will clear the batch reference
@@ -140,9 +133,16 @@ bool
 fd_fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx,
                 struct pipe_fence_handle *fence, uint64_t timeout)
 {
+   /* Note: for TC deferred fence, pctx->flush() may not have been called
+    * yet, so always do fence_flush() *first* before delegating to
+    * fence->last_fence
+    */
    if (!fence_flush(pctx, fence, timeout))
       return false;
 
+   if (fence->last_fence)
+      return fd_fence_finish(pscreen, pctx, fence->last_fence, timeout);
+
    if (fence->last_fence)
       fence = fence->last_fence;
 
@@ -220,6 +220,11 @@ fd_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *fence)
     */
    fence_flush(pctx, fence, 0);
 
+   if (fence->last_fence) {
+      fd_fence_server_sync(pctx, fence->last_fence);
+      return;
+   }
+
    /* if not an external fence, then nothing more to do without preemption: */
    if (!fence->submit_fence.use_fence_fd)
       return;
@@ -243,6 +248,9 @@ fd_fence_server_signal(struct pipe_context *pctx,
 int
 fd_fence_get_fd(struct pipe_screen *pscreen, struct pipe_fence_handle *fence)
 {
+   /* We don't expect deferred flush to be combined with fence-fd: */
+   assert(!fence->last_fence);
+
    assert(fence->submit_fence.use_fence_fd);
 
    /* NOTE: in the deferred fence case, the pctx we want is the threaded-ctx



More information about the mesa-commit mailing list