freedreno/drm: Simplify deferred submit flushing
authorRob Clark <robdclark@chromium.org>
Wed, 14 Dec 2022 21:18:14 +0000 (13:18 -0800)
committerMarge Bot <emma+marge@anholt.net>
Sat, 17 Dec 2022 19:14:12 +0000 (19:14 +0000)
Once we are sharing an out-fence for multiple deferred/merged submits
the complicated logic in fd_pipe_sp_flush() no longer works (or makes
sense), so just simplify all the paths into a single helper.

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

src/freedreno/drm/freedreno_device.c
src/freedreno/drm/freedreno_ringbuffer_sp.c

index a8ef77a664de85778a1319c482806c101e62906e..bbc7cfc8b13ae91dadf2480001db5ca17fd6723a 100644 (file)
@@ -153,6 +153,7 @@ fd_device_del(struct fd_device *dev)
       return;
 
    assert(list_is_empty(&dev->deferred_submits));
+   assert(!dev->deferred_submits_fence);
 
    if (dev->suballoc_bo)
       fd_bo_del(dev->suballoc_bo);
index dc482d11941d0405fdb50bde68046ad496e8a774..35d5236e1f7e49c1a535663f737278358c333929 100644 (file)
@@ -219,13 +219,19 @@ fd_submit_sp_flush_cleanup(void *job, void *gdata, int thread_index)
 }
 
 static void
-enqueue_submit_list(struct list_head *submit_list)
+flush_deferred_submits(struct fd_device *dev)
 {
-   struct fd_submit *submit = last_submit(submit_list);
+   simple_mtx_assert_locked(&dev->submit_lock);
+
+   if (list_is_empty(&dev->deferred_submits))
+      return;
+
+   struct fd_submit *submit = last_submit(&dev->deferred_submits);
    struct fd_submit_sp *fd_submit = to_fd_submit_sp(submit);
 
-   list_replace(submit_list, &fd_submit->submit_list);
-   list_inithead(submit_list);
+   list_replace(&dev->deferred_submits, &fd_submit->submit_list);
+   list_inithead(&dev->deferred_submits);
+   dev->deferred_cmds = 0;
 
    struct util_queue_fence *fence = &fd_submit->out_fence->ready;
 
@@ -275,13 +281,7 @@ fd_submit_sp_flush(struct fd_submit *submit, int in_fence_fd, bool use_fence_fd)
     */
    if (!list_is_empty(&dev->deferred_submits) &&
        (last_submit(&dev->deferred_submits)->pipe != submit->pipe)) {
-      struct list_head submit_list;
-
-      list_replace(&dev->deferred_submits, &submit_list);
-      list_inithead(&dev->deferred_submits);
-      dev->deferred_cmds = 0;
-
-      enqueue_submit_list(&submit_list);
+      flush_deferred_submits(dev);
    }
 
    list_addtail(&fd_submit_ref(submit)->node, &dev->deferred_submits);
@@ -314,16 +314,10 @@ fd_submit_sp_flush(struct fd_submit *submit, int in_fence_fd, bool use_fence_fd)
       return out_fence;
    }
 
-   struct list_head submit_list;
-
-   list_replace(&dev->deferred_submits, &submit_list);
-   list_inithead(&dev->deferred_submits);
-   dev->deferred_cmds = 0;
+   flush_deferred_submits(dev);
 
    simple_mtx_unlock(&dev->submit_lock);
 
-   enqueue_submit_list(&submit_list);
-
    return out_fence;
 }
 
@@ -331,42 +325,15 @@ void
 fd_pipe_sp_flush(struct fd_pipe *pipe, uint32_t fence)
 {
    struct fd_device *dev = pipe->dev;
-   struct list_head submit_list;
-
-   DEBUG_MSG("flush: %u", fence);
-
-   list_inithead(&submit_list);
 
    simple_mtx_lock(&dev->submit_lock);
 
    assert(!fd_fence_after(fence, pipe->last_enqueue_fence));
 
-   foreach_submit_safe (deferred_submit, &dev->deferred_submits) {
-      /* We should never have submits from multiple pipes in the deferred
-       * list.  If we did, we couldn't compare their fence to our fence,
-       * since each fd_pipe is an independent timeline.
-       */
-      if (deferred_submit->pipe != pipe)
-         break;
-
-      if (fd_fence_after(deferred_submit->fence, fence))
-         break;
-
-      list_del(&deferred_submit->node);
-      list_addtail(&deferred_submit->node, &submit_list);
-      dev->deferred_cmds -= fd_ringbuffer_cmd_count(deferred_submit->primary);
-   }
-
-   assert(dev->deferred_cmds == fd_dev_count_deferred_cmds(dev));
+   flush_deferred_submits(dev);
 
    simple_mtx_unlock(&dev->submit_lock);
 
-   if (list_is_empty(&submit_list))
-      goto flush_sync;
-
-   enqueue_submit_list(&submit_list);
-
-flush_sync:
    /* Once we are sure that we've enqueued at least up to the requested
     * submit, we need to be sure that submitq has caught up and flushed
     * them to the kernel