anv: add new gem/drm helpers
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Tue, 6 Aug 2019 12:56:40 +0000 (15:56 +0300)
committerMarge Bot <eric+marge@anholt.net>
Tue, 1 Sep 2020 16:40:11 +0000 (16:40 +0000)
Needed for dealing with the new DRM timeline syncobj ioctls.

v2: Make use of the anv_gem_get_drm_cap() parameter... (Jason)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/2901>

src/intel/vulkan/anv_device.c
src/intel/vulkan/anv_gem.c
src/intel/vulkan/anv_gem_stubs.c
src/intel/vulkan/anv_private.h

index d10567a939b79d860a501a0e2709953932467845..55d079e133f53c021996df810684951a0c3fa5e7 100644 (file)
@@ -28,8 +28,9 @@
 #include <sys/sysinfo.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <xf86drm.h>
 #include "drm-uapi/drm_fourcc.h"
+#include "drm-uapi/drm.h"
+#include <xf86drm.h>
 
 #include "anv_private.h"
 #include "util/debug.h"
@@ -439,6 +440,9 @@ anv_physical_device_try_create(struct anv_instance *instance,
    device->has_syncobj = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE_ARRAY);
    device->has_syncobj_wait = device->has_syncobj &&
                               anv_gem_supports_syncobj_wait(fd);
+   device->has_syncobj_wait_available =
+      anv_gem_get_drm_cap(fd, DRM_CAP_SYNCOBJ_TIMELINE) != 0;
+
    device->has_context_priority = anv_gem_has_context_priority(fd);
 
    result = anv_physical_device_init_heaps(device, fd);
@@ -451,6 +455,11 @@ anv_physical_device_try_create(struct anv_instance *instance,
    device->has_context_isolation =
       anv_gem_get_param(fd, I915_PARAM_HAS_CONTEXT_ISOLATION);
 
+   device->has_exec_timeline =
+      anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_TIMELINE_FENCES);
+   if (env_var_as_boolean("ANV_QUEUE_THREAD_DISABLE", false))
+      device->has_exec_timeline = false;
+
    device->always_use_bindless =
       env_var_as_boolean("ANV_ALWAYS_BINDLESS", false);
 
index fca72a9803e6536285e5cb6f10662cdae3e16d8d..fdc780cbb465841d87846af79db027bf3f4b096f 100644 (file)
@@ -285,6 +285,17 @@ anv_gem_get_param(int fd, uint32_t param)
    return 0;
 }
 
+uint64_t
+anv_gem_get_drm_cap(int fd, uint32_t capability)
+{
+   struct drm_get_cap cap = {
+      .capability = capability,
+   };
+
+   gen_ioctl(fd, DRM_IOCTL_GET_CAP, &cap);
+   return cap.value;
+}
+
 bool
 anv_gem_get_bit6_swizzle(int fd, uint32_t tiling)
 {
@@ -574,7 +585,7 @@ anv_gem_supports_syncobj_wait(int fd)
 
 int
 anv_gem_syncobj_wait(struct anv_device *device,
-                     uint32_t *handles, uint32_t num_handles,
+                     const uint32_t *handles, uint32_t num_handles,
                      int64_t abs_timeout_ns, bool wait_all)
 {
    struct drm_syncobj_wait args = {
@@ -589,3 +600,59 @@ anv_gem_syncobj_wait(struct anv_device *device,
 
    return gen_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_WAIT, &args);
 }
+
+int
+anv_gem_syncobj_timeline_wait(struct anv_device *device,
+                              const uint32_t *handles, const uint64_t *points,
+                              uint32_t num_items, int64_t abs_timeout_ns,
+                              bool wait_all, bool wait_materialize)
+{
+   assert(device->physical->has_syncobj_wait_available);
+
+   struct drm_syncobj_timeline_wait args = {
+      .handles = (uint64_t)(uintptr_t)handles,
+      .points = (uint64_t)(uintptr_t)points,
+      .count_handles = num_items,
+      .timeout_nsec = abs_timeout_ns,
+      .flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
+   };
+
+   if (wait_all)
+      args.flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL;
+   if (wait_materialize)
+      args.flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE;
+
+   return gen_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &args);
+}
+
+int
+anv_gem_syncobj_timeline_signal(struct anv_device *device,
+                                const uint32_t *handles, const uint64_t *points,
+                                uint32_t num_items)
+{
+   assert(device->physical->has_syncobj_wait_available);
+
+   struct drm_syncobj_timeline_array args = {
+      .handles = (uint64_t)(uintptr_t)handles,
+      .points = (uint64_t)(uintptr_t)points,
+      .count_handles = num_items,
+   };
+
+   return gen_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
+}
+
+int
+anv_gem_syncobj_timeline_query(struct anv_device *device,
+                               const uint32_t *handles, uint64_t *points,
+                               uint32_t num_items)
+{
+   assert(device->physical->has_syncobj_wait_available);
+
+   struct drm_syncobj_timeline_array args = {
+      .handles = (uint64_t)(uintptr_t)handles,
+      .points = (uint64_t)(uintptr_t)points,
+      .count_handles = num_items,
+   };
+
+   return gen_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
+}
index d6636d3ccd85e99996f5fcf920105592578df841..35285c08d7170f062e44b5764e1c9777db8a60ab 100644 (file)
@@ -129,6 +129,12 @@ anv_gem_get_param(int fd, uint32_t param)
    unreachable("Unused");
 }
 
+uint64_t
+anv_gem_get_drm_cap(int fd, uint32_t capability)
+{
+   return 0;
+}
+
 bool
 anv_gem_get_bit6_swizzle(int fd, uint32_t tiling)
 {
@@ -241,7 +247,7 @@ anv_gem_supports_syncobj_wait(int fd)
 
 int
 anv_gem_syncobj_wait(struct anv_device *device,
-                     uint32_t *handles, uint32_t num_handles,
+                     const uint32_t *handles, uint32_t num_handles,
                      int64_t abs_timeout_ns, bool wait_all)
 {
    unreachable("Unused");
@@ -252,3 +258,28 @@ anv_gem_reg_read(int fd, uint32_t offset, uint64_t *result)
 {
    unreachable("Unused");
 }
+
+int
+anv_gem_syncobj_timeline_wait(struct anv_device *device,
+                              const uint32_t *handles, const uint64_t *points,
+                              uint32_t num_items, int64_t abs_timeout_ns,
+                              bool wait_all, bool wait_materialize)
+{
+   unreachable("Unused");
+}
+
+int
+anv_gem_syncobj_timeline_signal(struct anv_device *device,
+                                const uint32_t *handles, const uint64_t *points,
+                                uint32_t num_items)
+{
+   unreachable("Unused");
+}
+
+int
+anv_gem_syncobj_timeline_query(struct anv_device *device,
+                               const uint32_t *handles, uint64_t *points,
+                               uint32_t num_items)
+{
+   unreachable("Unused");
+}
index e4a7aa3a6ebe5ae59caa6aad8fd9a6e631ca0559..54b1c730791bbd3eb6ed25a86ed61b9c8f4dd181 100644 (file)
@@ -1079,6 +1079,7 @@ struct anv_physical_device {
     bool                                        has_exec_fence;
     bool                                        has_syncobj;
     bool                                        has_syncobj_wait;
+    bool                                        has_syncobj_wait_available;
     bool                                        has_context_priority;
     bool                                        has_context_isolation;
     bool                                        has_mem_available;
@@ -1095,6 +1096,8 @@ struct anv_physical_device {
     bool                                        has_bindless_images;
     /** True if we can use bindless access for samplers */
     bool                                        has_bindless_samplers;
+    /** True if we can use timeline semaphores through execbuf */
+    bool                                        has_exec_timeline;
 
     /** True if we can read the GPU timestamp register
      *
@@ -1561,6 +1564,7 @@ int anv_gem_set_context_param(int fd, int context, uint32_t param,
 int anv_gem_get_context_param(int fd, int context, uint32_t param,
                               uint64_t *value);
 int anv_gem_get_param(int fd, uint32_t param);
+uint64_t anv_gem_get_drm_cap(int fd, uint32_t capability);
 int anv_gem_get_tiling(struct anv_device *device, uint32_t gem_handle);
 bool anv_gem_get_bit6_swizzle(int fd, uint32_t tiling);
 int anv_gem_gpu_get_reset_stats(struct anv_device *device,
@@ -1583,8 +1587,18 @@ int anv_gem_syncobj_import_sync_file(struct anv_device *device,
 void anv_gem_syncobj_reset(struct anv_device *device, uint32_t handle);
 bool anv_gem_supports_syncobj_wait(int fd);
 int anv_gem_syncobj_wait(struct anv_device *device,
-                         uint32_t *handles, uint32_t num_handles,
+                         const uint32_t *handles, uint32_t num_handles,
                          int64_t abs_timeout_ns, bool wait_all);
+int anv_gem_syncobj_timeline_wait(struct anv_device *device,
+                                  const uint32_t *handles, const uint64_t *points,
+                                  uint32_t num_items, int64_t abs_timeout_ns,
+                                  bool wait_all, bool wait_materialize);
+int anv_gem_syncobj_timeline_signal(struct anv_device *device,
+                                    const uint32_t *handles, const uint64_t *points,
+                                    uint32_t num_items);
+int anv_gem_syncobj_timeline_query(struct anv_device *device,
+                                   const uint32_t *handles, uint64_t *points,
+                                   uint32_t num_items);
 
 uint64_t anv_vma_alloc(struct anv_device *device,
                        uint64_t size, uint64_t align,