From a965ffad21d41f14e09babd18896bb962b326da4 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Tue, 6 Aug 2019 15:56:40 +0300 Subject: [PATCH] anv: add new gem/drm helpers 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 Reviewed-by: Jason Ekstrand Part-of: --- src/intel/vulkan/anv_device.c | 11 ++++- src/intel/vulkan/anv_gem.c | 69 +++++++++++++++++++++++++++++++- src/intel/vulkan/anv_gem_stubs.c | 33 ++++++++++++++- src/intel/vulkan/anv_private.h | 16 +++++++- 4 files changed, 125 insertions(+), 4 deletions(-) diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index d10567a939b..55d079e133f 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -28,8 +28,9 @@ #include #include #include -#include #include "drm-uapi/drm_fourcc.h" +#include "drm-uapi/drm.h" +#include #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); diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c index fca72a9803e..fdc780cbb46 100644 --- a/src/intel/vulkan/anv_gem.c +++ b/src/intel/vulkan/anv_gem.c @@ -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); +} diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c index d6636d3ccd8..35285c08d71 100644 --- a/src/intel/vulkan/anv_gem_stubs.c +++ b/src/intel/vulkan/anv_gem_stubs.c @@ -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"); +} diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index e4a7aa3a6eb..54b1c730791 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -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, -- 2.30.2