freedreno: last_fence optimization for TC async flushes
authorRob Clark <robdclark@chromium.org>
Sun, 18 Apr 2021 22:29:32 +0000 (15:29 -0700)
committerMarge Bot <eric+marge@anholt.net>
Wed, 28 Apr 2021 15:36:42 +0000 (15:36 +0000)
Without deferred flushes, we would track the last_fence any time when
there had be no rendering/etc since the last flush, to avoid creating
empty batches simply for the purpose of getting a fence.  We can do the
same thing with deferred flushes, where the fence is created from the
frontend thread before we know what will be flushed, by repopulating
the pre-created fence.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10444>

src/gallium/drivers/freedreno/freedreno_context.c
src/gallium/drivers/freedreno/freedreno_fence.c
src/gallium/drivers/freedreno/freedreno_fence.h

index 1ce2a11..1c7dbfc 100644 (file)
@@ -77,11 +77,15 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
       fd_fence_set_batch(*fencep, batch);
       fd_fence_ref(&batch->fence, *fencep);
 
-      /* We (a) cannot substitute the provided fence with last_fence,
-       * and (b) need fd_fence_populate() to be eventually called on
-       * the fence that was pre-created in frontend-thread:
+      /* If we have nothing to flush, update the pre-created unflushed
+       * fence with the current state of the last-fence:
        */
-      fd_fence_ref(&ctx->last_fence, NULL);
+      if (ctx->last_fence) {
+         fd_fence_repopulate(*fencep, ctx->last_fence);
+         fd_fence_ref(&fence, *fencep);
+         fd_bc_dump(ctx->screen, "%p: (deferred) reuse last_fence, remaining:\n", ctx);
+         goto out;
+      }
 
       /* async flush is not compatible with deferred flush, since
        * nothing triggers the batch flush which fence_flush() would
index dbd58f6..c8f4e3a 100644 (file)
@@ -129,6 +129,13 @@ fd_fence_populate(struct pipe_fence_handle *fence, uint32_t timestamp,
    }
 }
 
+void
+fd_fence_repopulate(struct pipe_fence_handle *fence, struct pipe_fence_handle *last_fence)
+{
+   int fence_fd = (last_fence->fence_fd == -1) ? -1 : dup(last_fence->fence_fd);
+   fd_fence_populate(fence, last_fence->timestamp, fence_fd);
+}
+
 static void
 fd_fence_destroy(struct pipe_fence_handle *fence)
 {
index 7539996..c359f09 100644 (file)
@@ -31,6 +31,8 @@
 
 void fd_fence_populate(struct pipe_fence_handle *fence, uint32_t timestamp,
                        int fence_fd);
+void fd_fence_repopulate(struct pipe_fence_handle *fence,
+                         struct pipe_fence_handle *last_fence);
 void fd_fence_ref(struct pipe_fence_handle **ptr,
                   struct pipe_fence_handle *pfence);
 bool fd_fence_finish(struct pipe_screen *pscreen, struct pipe_context *ctx,