turnip: preliminary support for tu_QueueWaitIdle
authorChia-I Wu <olvaffe@gmail.com>
Thu, 10 Jan 2019 22:07:50 +0000 (14:07 -0800)
committerChia-I Wu <olvaffe@gmail.com>
Mon, 11 Mar 2019 17:01:41 +0000 (10:01 -0700)
This creates a new fd on each queue submit.  I do not go with
DRM_IOCTL_MSM_WAIT_FENCE solely because the path is marked legacy.
Otherwise, we can use the  fence id rather than requesting a fence
fd until external fences are supported and enabled.

src/freedreno/vulkan/tu_device.c
src/freedreno/vulkan/tu_private.h

index d5a65aadf535f58920227e1cccb485ea3e135ed6..11d200e2f036afd152f71e8856de9859d3883d1e 100644 (file)
@@ -28,6 +28,7 @@
 #include "tu_private.h"
 
 #include <fcntl.h>
+#include <libsync.h>
 #include <stdbool.h>
 #include <string.h>
 #include <sys/mman.h>
@@ -953,12 +954,17 @@ tu_queue_init(struct tu_device *device,
    if (ret)
       return VK_ERROR_INITIALIZATION_FAILED;
 
+   queue->submit_fence_fd = -1;
+
    return VK_SUCCESS;
 }
 
 static void
 tu_queue_finish(struct tu_queue *queue)
 {
+   if (queue->submit_fence_fd >= 0) {
+      close(queue->submit_fence_fd);
+   }
    tu_drm_submitqueue_close(queue->device, queue->msm_queue_id);
 }
 
@@ -1166,6 +1172,7 @@ tu_QueueSubmit(VkQueue _queue,
 
    for (uint32_t i = 0; i < submitCount; ++i) {
       const VkSubmitInfo *submit = pSubmits + i;
+      const bool last_submit = (i == submitCount - 1);
       struct tu_bo_list bo_list;
       tu_bo_list_init(&bo_list);
 
@@ -1199,8 +1206,13 @@ tu_QueueSubmit(VkQueue _queue,
          bos[i].presumed = 0;
       }
 
+      uint32_t flags = MSM_PIPE_3D0;
+      if (last_submit) {
+         flags |= MSM_SUBMIT_FENCE_FD_OUT;
+      }
+
       struct drm_msm_gem_submit req = {
-         .flags = MSM_PIPE_3D0,
+         .flags = flags,
          .queueid = queue->msm_queue_id,
          .bos = (uint64_t)(uintptr_t)bos,
          .nr_bos = bo_list.count,
@@ -1217,6 +1229,14 @@ tu_QueueSubmit(VkQueue _queue,
       }
 
       tu_bo_list_destroy(&bo_list);
+
+      if (last_submit) {
+         /* no need to merge fences as queue execution is serialized */
+         if (queue->submit_fence_fd >= 0) {
+            close(queue->submit_fence_fd);
+         }
+         queue->submit_fence_fd = req.fence_fd;
+      }
    }
    return VK_SUCCESS;
 }
@@ -1224,6 +1244,17 @@ tu_QueueSubmit(VkQueue _queue,
 VkResult
 tu_QueueWaitIdle(VkQueue _queue)
 {
+   TU_FROM_HANDLE(tu_queue, queue, _queue);
+
+   if (queue->submit_fence_fd >= 0) {
+      int ret = sync_wait(queue->submit_fence_fd, -1);
+      if (ret)
+         tu_loge("sync_wait on fence fd %d failed", queue->submit_fence_fd);
+
+      close(queue->submit_fence_fd);
+      queue->submit_fence_fd = -1;
+   }
+
    return VK_SUCCESS;
 }
 
index 4602628169ec07ad435493b7639b26678300d060..53f493a61aac0125962ed5246f3b6fa803416f59 100644 (file)
@@ -401,6 +401,7 @@ struct tu_queue
    VkDeviceQueueCreateFlags flags;
 
    uint32_t msm_queue_id;
+   int submit_fence_fd;
 };
 
 struct tu_device