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>
#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"
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);
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);
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)
{
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 = {
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);
+}
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)
{
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");
{
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");
+}
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;
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
*
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,
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,