* [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests
@ 2020-07-31 13:41 Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores Lionel Landwerlin
` (6 more replies)
0 siblings, 7 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2020-07-31 13:41 UTC (permalink / raw)
To: igt-dev
Hi all,
This series was Acked by Daniel (Thanks!).
Just resending to do a run with the kernel patches.
Cheers,
Chunming Zhou (1):
igt: add timeline test cases
Lionel Landwerlin (4):
drm-uapi: bump i915_drm.h for timeline semaphores
tests/syncobj_timeline: add more timeline tests
tests/i915/exec_fence: add timeline fence tests
tests/i915/gem_exec_fence: add engine chaining tests
include/drm-uapi/i915_drm.h | 65 +-
lib/igt_syncobj.c | 236 ++++++
lib/igt_syncobj.h | 22 +
lib/intel_reg.h | 2 +
tests/i915/gem_exec_fence.c | 1319 ++++++++++++++++++++++++++++++
tests/meson.build | 1 +
tests/syncobj_timeline.c | 1537 +++++++++++++++++++++++++++++++++++
7 files changed, 3179 insertions(+), 3 deletions(-)
create mode 100644 tests/syncobj_timeline.c
--
2.28.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 13+ messages in thread
* [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores
2020-07-31 13:41 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
@ 2020-07-31 13:41 ` Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 2/5] igt: add timeline test cases Lionel Landwerlin
` (5 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2020-07-31 13:41 UTC (permalink / raw)
To: igt-dev
To be updated with proper drm-next snapshot.
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
include/drm-uapi/i915_drm.h | 65 +++++++++++++++++++++++++++++++++++--
1 file changed, 62 insertions(+), 3 deletions(-)
diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index 2b55af13..6de897f0 100644
--- a/include/drm-uapi/i915_drm.h
+++ b/include/drm-uapi/i915_drm.h
@@ -619,6 +619,13 @@ typedef struct drm_i915_irq_wait {
*/
#define I915_PARAM_PERF_REVISION 54
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
+ * timeline syncobj through drm_i915_gem_execbuf_ext_timeline_fences. See
+ * I915_EXEC_USE_EXTENSIONS.
+ */
+#define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
+
+
/* Must be kept compact -- no holes and well documented */
typedef struct drm_i915_getparam {
@@ -1046,6 +1053,42 @@ struct drm_i915_gem_exec_fence {
__u32 flags;
};
+enum drm_i915_gem_execbuffer_ext {
+ /**
+ * See drm_i915_gem_execbuf_ext_timeline_fences.
+ */
+ DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES = 1,
+
+ DRM_I915_GEM_EXECBUFFER_EXT_MAX /* non-ABI */
+};
+
+/**
+ * This structure describes an array of drm_syncobj and associated points for
+ * timeline variants of drm_syncobj. It is invalid to append this structure to
+ * the execbuf if I915_EXEC_FENCE_ARRAY is set.
+ */
+struct drm_i915_gem_execbuffer_ext_timeline_fences {
+ struct i915_user_extension base;
+
+ /**
+ * Number of element in the handles_ptr & value_ptr arrays.
+ */
+ __u64 fence_count;
+
+ /**
+ * Pointer to an array of struct drm_i915_gem_exec_fence of length
+ * fence_count.
+ */
+ __u64 handles_ptr;
+
+ /**
+ * Pointer to an array of u64 values of length fence_count. Values
+ * must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
+ * drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+ */
+ __u64 values_ptr;
+};
+
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
@@ -1062,8 +1105,15 @@ struct drm_i915_gem_execbuffer2 {
__u32 num_cliprects;
/**
* This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
- * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
- * struct drm_i915_gem_exec_fence *fences.
+ * & I915_EXEC_USE_EXTENSIONS are not set.
+ *
+ * If I915_EXEC_FENCE_ARRAY is set, then this is a pointer to an array
+ * of struct drm_i915_gem_exec_fence and num_cliprects is the length
+ * of the array.
+ *
+ * If I915_EXEC_USE_EXTENSIONS is set, then this is a pointer to a
+ * single struct drm_i915_gem_base_execbuffer_ext and num_cliprects is
+ * 0.
*/
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (0x3f)
@@ -1181,7 +1231,16 @@ struct drm_i915_gem_execbuffer2 {
*/
#define I915_EXEC_FENCE_SUBMIT (1 << 20)
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SUBMIT << 1))
+/*
+ * Setting I915_EXEC_USE_EXTENSIONS implies that
+ * drm_i915_gem_execbuffer2.cliprects_ptr is treated as a pointer to an linked
+ * list of i915_user_extension. Each i915_user_extension node is the base of a
+ * larger structure. The list of supported structures are listed in the
+ * drm_i915_gem_execbuffer_ext enum.
+ */
+#define I915_EXEC_USE_EXTENSIONS (1 << 21)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_USE_EXTENSIONS<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
--
2.28.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [igt-dev] [PATCH i-g-t 2/5] igt: add timeline test cases
2020-07-31 13:41 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores Lionel Landwerlin
@ 2020-07-31 13:41 ` Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 3/5] tests/syncobj_timeline: add more timeline tests Lionel Landwerlin
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2020-07-31 13:41 UTC (permalink / raw)
To: igt-dev; +Cc: Chunming Zhou
From: Chunming Zhou <david1.zhou@amd.com>
v2: adapt to new transfer ioctl
v3: Drop useless uint64_t casts (Lionel)
Fix timeline query prototypes (Lionel)
Test multi wait with timeline & binary syncobjs (Lionel)
v4: Switch from drmIoctl to igt_ioctl in tests/*.c (Chris)
Clear out errno in helper functions (Chris)
v5: Fix lib comments on transfer helpers (Lionel)
v6: Add igt_describe() (Lionel)
Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
lib/igt_syncobj.c | 237 ++++++++
lib/igt_syncobj.h | 19 +
tests/meson.build | 1 +
tests/syncobj_timeline.c | 1150 ++++++++++++++++++++++++++++++++++++++
4 files changed, 1407 insertions(+)
create mode 100644 tests/syncobj_timeline.c
diff --git a/lib/igt_syncobj.c b/lib/igt_syncobj.c
index ad23faaf..b211dfef 100644
--- a/lib/igt_syncobj.c
+++ b/lib/igt_syncobj.c
@@ -307,3 +307,240 @@ syncobj_signal(int fd, uint32_t *handles, uint32_t count)
{
igt_assert_eq(__syncobj_signal(fd, handles, count), 0);
}
+
+static int
+__syncobj_timeline_signal(int fd, uint32_t *handles, uint64_t *points, uint32_t count)
+{
+ struct drm_syncobj_timeline_array array = { 0 };
+ int err = 0;
+
+ array.handles = to_user_pointer(handles);
+ array.points = to_user_pointer(points);
+ array.count_handles = count;
+ if (igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &array)) {
+ err = -errno;
+ igt_assume(err);
+ errno = 0;
+ }
+ return err;
+}
+
+/**
+ * syncobj_signal:
+ * @fd: The DRM file descriptor.
+ * @handles: Array of syncobj handles to signal
+ * @points: List of point of handles to signal.
+ * @count: Count of syncobj handles.
+ *
+ * Signal a set of syncobjs.
+ */
+void
+syncobj_timeline_signal(int fd, uint32_t *handles, uint64_t *points, uint32_t count)
+{
+ igt_assert_eq(__syncobj_timeline_signal(fd, handles, points, count), 0);
+}
+int
+__syncobj_timeline_wait_ioctl(int fd, struct drm_syncobj_timeline_wait *args)
+{
+ int err = 0;
+ if (igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, args)) {
+ err = -errno;
+ igt_assume(err);
+ errno = 0;
+ }
+ return err;
+}
+static int
+__syncobj_timeline_wait(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+ struct drm_syncobj_timeline_wait args;
+ int ret;
+
+ args.handles = to_user_pointer(handles);
+ args.points = to_user_pointer(points);
+ args.timeout_nsec = timeout_nsec;
+ args.count_handles = num_handles;
+ args.flags = flags;
+ args.first_signaled = 0;
+ args.pad = 0;
+
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &args);
+ if (ret < 0) {
+ ret = -errno;
+ igt_assume(ret);
+ errno = 0;
+ }
+
+ if (first_signaled)
+ *first_signaled = args.first_signaled;
+
+ return ret;
+}
+int
+syncobj_timeline_wait_err(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags)
+{
+ return __syncobj_timeline_wait(fd, handles, points, num_handles,
+ timeout_nsec, flags, NULL);
+}
+
+/**
+ * syncobj_timeline_wait:
+ * @fd: The DRM file descriptor
+ * @handles: List of syncobj handles to wait for.
+ * @points: List of point of handles to wait for.
+ * @num_handles: Count of handles
+ * @timeout_nsec: Absolute wait timeout in nanoseconds.
+ * @flags: Wait ioctl flags.
+ * @first_signaled: Returned handle for first signaled syncobj.
+ *
+ * Waits in the kernel for any/all the requested syncobjs timeline point
+ * using the timeout and flags.
+ * Returns: bool value - false = timedout, true = signaled
+ */
+bool
+syncobj_timeline_wait(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+ int ret;
+
+ ret = __syncobj_timeline_wait(fd, handles, points, num_handles,
+ timeout_nsec, flags, first_signaled);
+ if (ret == -ETIME)
+ return false;
+ igt_assert_eq(ret, 0);
+
+ return true;
+
+}
+
+static int
+__syncobj_timeline_query(int fd, uint32_t *handles, uint64_t *points,
+ uint32_t handle_count)
+{
+ struct drm_syncobj_timeline_array args;
+ int ret;
+
+ args.handles = to_user_pointer(handles);
+ args.points = to_user_pointer(points);
+ args.count_handles = handle_count;
+ args.flags = 0;
+
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
+ if (ret) {
+ ret = -errno;
+ igt_assume(ret);
+ errno = 0;
+ }
+
+ return ret;
+}
+
+/**
+ * syncobj_timeline_query:
+ * @fd: The DRM file descriptor.
+ * @handles: Array of syncobj handles.
+ * @points: Array of syncobj points queried.
+ * @count: Count of syncobj handles.
+ *
+ * Queries a set of syncobjs.
+ */
+void
+syncobj_timeline_query(int fd, uint32_t *handles, uint64_t *points,
+ uint32_t count)
+{
+ igt_assert_eq(__syncobj_timeline_query(fd, handles, points, count), 0);
+}
+
+static int
+__syncobj_binary_to_timeline(int fd, uint32_t timeline_handle,
+ uint64_t point, uint32_t binary_handle)
+{
+ struct drm_syncobj_transfer args;
+ int ret;
+
+ args.src_handle = binary_handle;
+ args.dst_handle = timeline_handle;
+ args.src_point = 0;
+ args.dst_point = point;
+ args.flags = 0;
+ args.pad = 0;
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
+ if (ret) {
+ ret = -errno;
+ igt_assume(ret);
+ errno = 0;
+ }
+
+ return ret;
+}
+
+/**
+ * syncobj_binary_to_timeline:
+ * @fd: The DRM file descriptor.
+ * @timeline_handle: A syncobj timeline handle
+ * @point: A syncobj timeline point in the timeline handle
+ * @binary_handle: A syncobj binary handle
+ *
+ * Transfers a DMA fence from a binary syncobj into a timeline syncobj
+ * at a given point on the timeline.
+ */
+void
+syncobj_binary_to_timeline(int fd, uint32_t timeline_handle,
+ uint64_t point, uint32_t binary_handle)
+{
+ igt_assert_eq(__syncobj_binary_to_timeline(fd, timeline_handle, point,
+ binary_handle), 0);
+}
+
+static int
+__syncobj_timeline_to_binary(int fd, uint32_t binary_handle,
+ uint32_t timeline_handle,
+ uint64_t point,
+ uint32_t flags)
+{
+ struct drm_syncobj_transfer args;
+ int ret;
+
+ args.dst_handle = binary_handle;
+ args.src_handle = timeline_handle;
+ args.dst_point = 0;
+ args.src_point = point;
+ args.flags = flags;
+ args.pad = 0;
+ ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
+ if (ret) {
+ ret = -errno;
+ igt_assert(ret);
+ }
+
+ errno = 0;
+ return ret;
+}
+
+/**
+ * syncobj_binary_to_timeline:
+ * @fd: The DRM file descriptor.
+ * @binary_handle: A syncobj binary handle
+ * @timeline_handle: A syncobj timeline handle
+ * @point: A syncobj timeline point in the timeline handle
+ *
+ * Transfers DMA fence from a given point from timeline syncobj into a
+ * binary syncobj.
+ */
+void
+syncobj_timeline_to_binary(int fd, uint32_t binary_handle,
+ uint32_t timeline_handle,
+ uint64_t point,
+ uint32_t flags)
+{
+ igt_assert_eq(__syncobj_timeline_to_binary(fd, binary_handle,
+ timeline_handle, point,
+ flags), 0);
+}
diff --git a/lib/igt_syncobj.h b/lib/igt_syncobj.h
index 51ad2364..20f1f18f 100644
--- a/lib/igt_syncobj.h
+++ b/lib/igt_syncobj.h
@@ -41,7 +41,26 @@ int syncobj_wait_err(int fd, uint32_t *handles, uint32_t count,
bool syncobj_wait(int fd, uint32_t *handles, uint32_t count,
uint64_t abs_timeout_nsec, uint32_t flags,
uint32_t *first_signaled);
+int __syncobj_timeline_wait_ioctl(int fd,
+ struct drm_syncobj_timeline_wait *args);
+bool syncobj_timeline_wait(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+int syncobj_timeline_wait_err(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags);
void syncobj_reset(int fd, uint32_t *handles, uint32_t count);
void syncobj_signal(int fd, uint32_t *handles, uint32_t count);
+void syncobj_timeline_query(int fd, uint32_t *handles, uint64_t *points,
+ uint32_t count);
+void syncobj_binary_to_timeline(int fd, uint32_t timeline_handle,
+ uint64_t point, uint32_t binary_handle);
+void syncobj_timeline_to_binary(int fd, uint32_t binary_handle,
+ uint32_t timeline_handle,
+ uint64_t point,
+ uint32_t flags);
+void syncobj_timeline_signal(int fd, uint32_t *handles, uint64_t *points,
+ uint32_t count);
#endif /* IGT_SYNCOBJ_H */
diff --git a/tests/meson.build b/tests/meson.build
index d7f3b373..684de043 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -87,6 +87,7 @@ test_progs = [
'prime_vgem',
'syncobj_basic',
'syncobj_wait',
+ 'syncobj_timeline',
'template',
'tools_test',
'v3d_get_bo_offset',
diff --git a/tests/syncobj_timeline.c b/tests/syncobj_timeline.c
new file mode 100644
index 00000000..82fc08aa
--- /dev/null
+++ b/tests/syncobj_timeline.c
@@ -0,0 +1,1150 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+#include "sw_sync.h"
+#include "igt_syncobj.h"
+#include <unistd.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include <pthread.h>
+#include <signal.h>
+#include "drm.h"
+
+IGT_TEST_DESCRIPTION("Tests for the drm timeline sync object API");
+
+/* One tenth of a second */
+#define SHORT_TIME_NSEC 100000000ull
+
+#define NSECS_PER_SEC 1000000000ull
+
+static uint64_t
+gettime_ns(void)
+{
+ struct timespec current;
+ clock_gettime(CLOCK_MONOTONIC, ¤t);
+ return (uint64_t)current.tv_sec * NSECS_PER_SEC + current.tv_nsec;
+}
+
+static void
+sleep_nsec(uint64_t time_nsec)
+{
+ struct timespec t;
+ t.tv_sec = time_nsec / NSECS_PER_SEC;
+ t.tv_nsec = time_nsec % NSECS_PER_SEC;
+ igt_assert_eq(nanosleep(&t, NULL), 0);
+}
+
+static uint64_t
+short_timeout(void)
+{
+ return gettime_ns() + SHORT_TIME_NSEC;
+}
+
+static int
+syncobj_attach_sw_sync(int fd, uint32_t handle, uint64_t point)
+{
+ int timeline, fence;
+
+ timeline = sw_sync_timeline_create();
+ fence = sw_sync_timeline_create_fence(timeline, 1);
+
+ if (point == 0) {
+ syncobj_import_sync_file(fd, handle, fence);
+ } else {
+ uint32_t syncobj = syncobj_create(fd, 0);
+
+ syncobj_import_sync_file(fd, syncobj, fence);
+ syncobj_binary_to_timeline(fd, handle, point, syncobj);
+ syncobj_destroy(fd, syncobj);
+ }
+
+ close(fence);
+
+ return timeline;
+}
+
+static void
+syncobj_trigger(int fd, uint32_t handle, uint64_t point)
+{
+ int timeline = syncobj_attach_sw_sync(fd, handle, point);
+ sw_sync_timeline_inc(timeline, 1);
+ close(timeline);
+}
+
+static timer_t
+set_timer(void (*cb)(union sigval), void *ptr, int i, uint64_t nsec)
+{
+ timer_t timer;
+ struct sigevent sev;
+ struct itimerspec its;
+
+ memset(&sev, 0, sizeof(sev));
+ sev.sigev_notify = SIGEV_THREAD;
+ if (ptr)
+ sev.sigev_value.sival_ptr = ptr;
+ else
+ sev.sigev_value.sival_int = i;
+ sev.sigev_notify_function = cb;
+ igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
+
+ memset(&its, 0, sizeof(its));
+ its.it_value.tv_sec = nsec / NSEC_PER_SEC;
+ its.it_value.tv_nsec = nsec % NSEC_PER_SEC;
+ igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
+
+ return timer;
+}
+
+struct fd_handle_pair {
+ int fd;
+ uint32_t handle;
+ uint64_t point;
+};
+
+static void
+timeline_inc_func(union sigval sigval)
+{
+ sw_sync_timeline_inc(sigval.sival_int, 1);
+}
+
+static void
+syncobj_trigger_free_pair_func(union sigval sigval)
+{
+ struct fd_handle_pair *pair = sigval.sival_ptr;
+ syncobj_trigger(pair->fd, pair->handle, pair->point);
+ free(pair);
+}
+
+static timer_t
+syncobj_trigger_delayed(int fd, uint32_t syncobj, uint64_t point, uint64_t nsec)
+{
+ struct fd_handle_pair *pair = malloc(sizeof(*pair));
+
+ pair->fd = fd;
+ pair->handle = syncobj;
+ pair->point = point;
+
+ return set_timer(syncobj_trigger_free_pair_func, pair, 0, nsec);
+}
+
+static const char *test_wait_bad_flags_desc =
+ "Verifies that an invalid value in drm_syncobj_timeline_wait::flags is"
+ " rejected";
+static void
+test_wait_bad_flags(int fd)
+{
+ struct drm_syncobj_timeline_wait wait = {};
+ wait.flags = 0xdeadbeef;
+ igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -EINVAL);
+}
+
+static const char *test_wait_zero_handles_desc =
+ "Verifies that waiting on an empty list of invalid syncobj handles is"
+ " rejected";
+static void
+test_wait_zero_handles(int fd)
+{
+ struct drm_syncobj_timeline_wait wait = {};
+ igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -EINVAL);
+}
+
+static const char *test_wait_illegal_handle_desc =
+ "Verifies that waiting on an invalid syncobj handle is rejected";
+static void
+test_wait_illegal_handle(int fd)
+{
+ struct drm_syncobj_timeline_wait wait = {};
+ uint32_t handle = 0;
+
+ wait.count_handles = 1;
+ wait.handles = to_user_pointer(&handle);
+ igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -ENOENT);
+}
+
+static const char *test_query_zero_handles_desc =
+ "Verifies that querying an empty list of syncobj handles is rejected";
+static void
+test_query_zero_handles(int fd)
+{
+ struct drm_syncobj_timeline_array args = {};
+ int ret;
+
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
+ igt_assert(ret == -1 && errno == EINVAL);
+}
+
+static const char *test_query_illegal_handle_desc =
+ "Verifies that querying an invalid syncobj handle is rejected";
+static void
+test_query_illegal_handle(int fd)
+{
+ struct drm_syncobj_timeline_array args = {};
+ uint32_t handle = 0;
+ int ret;
+
+ args.count_handles = 1;
+ args.handles = to_user_pointer(&handle);
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &args);
+ igt_assert(ret == -1 && errno == ENOENT);
+}
+
+static const char *test_query_one_illegal_handle_desc =
+ "Verifies that querying a list of invalid syncobj handle including an"
+ " invalid one is rejected";
+static void
+test_query_one_illegal_handle(int fd)
+{
+ struct drm_syncobj_timeline_array array = {};
+ uint32_t syncobjs[3];
+ uint64_t initial_point = 1;
+ int ret;
+
+ syncobjs[0] = syncobj_create(fd, 0);
+ syncobjs[1] = 0;
+ syncobjs[2] = syncobj_create(fd, 0);
+
+ syncobj_timeline_signal(fd, &syncobjs[0], &initial_point, 1);
+ syncobj_timeline_signal(fd, &syncobjs[2], &initial_point, 1);
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[0],
+ &initial_point, 1, 0, 0), 0);
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[2],
+ &initial_point, 1, 0, 0), 0);
+
+ array.count_handles = 3;
+ array.handles = to_user_pointer(syncobjs);
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &array);
+ igt_assert(ret == -1 && errno == ENOENT);
+
+ syncobj_destroy(fd, syncobjs[0]);
+ syncobj_destroy(fd, syncobjs[2]);
+}
+
+static const char *test_query_bad_pad_desc =
+ "Verify that querying a timeline syncobj with an invalid"
+ " drm_syncobj_timeline_array::flags field is rejected";
+static void
+test_query_bad_pad(int fd)
+{
+ struct drm_syncobj_timeline_array array = {};
+ uint32_t handle = 0;
+ int ret;
+
+ array.flags = 0xdeadbeef;
+ array.count_handles = 1;
+ array.handles = to_user_pointer(&handle);
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, &array);
+ igt_assert(ret == -1 && errno == EINVAL);
+}
+
+static const char *test_signal_zero_handles_desc =
+ "Verify that signaling an empty list of syncobj handles is rejected";
+static void
+test_signal_zero_handles(int fd)
+{
+ struct drm_syncobj_timeline_array args = {};
+ int ret;
+
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
+ igt_assert(ret == -1 && errno == EINVAL);
+}
+
+static const char *test_signal_illegal_handle_desc =
+ "Verify that signaling an invalid syncobj handle is rejected";
+static void
+test_signal_illegal_handle(int fd)
+{
+ struct drm_syncobj_timeline_array args = {};
+ uint32_t handle = 0;
+ int ret;
+
+ args.count_handles = 1;
+ args.handles = to_user_pointer(&handle);
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
+ igt_assert(ret == -1 && errno == ENOENT);
+}
+
+static void
+test_signal_illegal_point(int fd)
+{
+ struct drm_syncobj_timeline_array args = {};
+ uint32_t handle = 1;
+ uint64_t point = 0;
+ int ret;
+
+ args.count_handles = 1;
+ args.handles = to_user_pointer(&handle);
+ args.points = to_user_pointer(&point);
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &args);
+ igt_assert(ret == -1 && errno == ENOENT);
+}
+
+static const char *test_signal_one_illegal_handle_desc =
+ "Verify that an invalid syncobj handle in drm_syncobj_timeline_array is"
+ " rejected for signaling";
+static void
+test_signal_one_illegal_handle(int fd)
+{
+ struct drm_syncobj_timeline_array array = {};
+ uint32_t syncobjs[3];
+ uint64_t initial_point = 1;
+ int ret;
+
+ syncobjs[0] = syncobj_create(fd, 0);
+ syncobjs[1] = 0;
+ syncobjs[2] = syncobj_create(fd, 0);
+
+ syncobj_timeline_signal(fd, &syncobjs[0], &initial_point, 1);
+ syncobj_timeline_signal(fd, &syncobjs[2], &initial_point, 1);
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[0],
+ &initial_point, 1, 0, 0), 0);
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[2],
+ &initial_point, 1, 0, 0), 0);
+
+ array.count_handles = 3;
+ array.handles = to_user_pointer(syncobjs);
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &array);
+ igt_assert(ret == -1 && errno == ENOENT);
+
+ syncobj_destroy(fd, syncobjs[0]);
+ syncobj_destroy(fd, syncobjs[2]);
+}
+
+static const char *test_signal_bad_pad_desc =
+ "Verifies that an invalid value in drm_syncobj_timeline_array.flags is"
+ " rejected";
+static void
+test_signal_bad_pad(int fd)
+{
+ struct drm_syncobj_timeline_array array = {};
+ uint32_t handle = 0;
+ int ret;
+
+ array.flags = 0xdeadbeef;
+ array.count_handles = 1;
+ array.handles = to_user_pointer(&handle);
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, &array);
+ igt_assert(ret == -1 && errno == EINVAL);
+}
+
+static const char *test_signal_array_desc =
+ "Verifies the signaling of a list of timeline syncobj";
+static void
+test_signal_array(int fd)
+{
+ uint32_t syncobjs[4];
+ uint64_t points[4] = {1, 1, 1, 0};
+
+ syncobjs[0] = syncobj_create(fd, 0);
+ syncobjs[1] = syncobj_create(fd, 0);
+ syncobjs[2] = syncobj_create(fd, 0);
+ syncobjs[3] = syncobj_create(fd, 0);
+
+ syncobj_timeline_signal(fd, syncobjs, points, 4);
+ igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs,
+ points, 3, 0, 0), 0);
+ igt_assert_eq(syncobj_wait_err(fd, &syncobjs[3], 1, 0, 0), 0);
+
+ syncobj_destroy(fd, syncobjs[0]);
+ syncobj_destroy(fd, syncobjs[1]);
+ syncobj_destroy(fd, syncobjs[2]);
+ syncobj_destroy(fd, syncobjs[3]);
+}
+
+static const char *test_transfer_illegal_handle_desc =
+ "Verifies that an invalid syncobj handle is rejected in"
+ " drm_syncobj_transfer";
+static void
+test_transfer_illegal_handle(int fd)
+{
+ struct drm_syncobj_transfer args = {};
+ uint32_t handle = 0;
+ int ret;
+
+ args.src_handle = to_user_pointer(&handle);
+ args.dst_handle = to_user_pointer(&handle);
+ args.src_point = 1;
+ args.dst_point = 0;
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
+ igt_assert(ret == -1 && errno == ENOENT);
+}
+
+static const char *test_transfer_bad_pad_desc =
+ "Verifies that invalid drm_syncobj_transfer::pad field value is"
+ " rejected";
+static void
+test_transfer_bad_pad(int fd)
+{
+ struct drm_syncobj_transfer arg = {};
+ uint32_t handle = 0;
+ int ret;
+
+ arg.pad = 0xdeadbeef;
+ arg.src_handle = to_user_pointer(&handle);
+ arg.dst_handle = to_user_pointer(&handle);
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &arg);
+ igt_assert(ret == -1 && errno == EINVAL);
+}
+
+#define WAIT_FOR_SUBMIT (1 << 0)
+#define WAIT_ALL (1 << 1)
+#define WAIT_AVAILABLE (1 << 2)
+#define WAIT_UNSUBMITTED (1 << 3)
+#define WAIT_SUBMITTED (1 << 4)
+#define WAIT_SIGNALED (1 << 5)
+#define WAIT_FLAGS_MAX (1 << 6) - 1
+
+static uint32_t
+flags_for_test_flags(uint32_t test_flags)
+{
+ uint32_t flags = 0;
+
+ if (test_flags & WAIT_FOR_SUBMIT)
+ flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+
+ if (test_flags & WAIT_AVAILABLE)
+ flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE;
+
+ if (test_flags & WAIT_ALL)
+ flags |= DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL;
+
+ return flags;
+}
+
+static const char *test_signal_wait_desc =
+ "Verifies wait behavior on a single timeline syncobj";
+static void
+test_single_wait(int fd, uint32_t test_flags, int expect)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint32_t flags = flags_for_test_flags(test_flags);
+ uint64_t point = 1;
+ int timeline = -1;
+
+ if (test_flags & (WAIT_SUBMITTED | WAIT_SIGNALED))
+ timeline = syncobj_attach_sw_sync(fd, syncobj, point);
+
+ if (test_flags & WAIT_SIGNALED)
+ sw_sync_timeline_inc(timeline, 1);
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point, 1,
+ 0, flags), expect);
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point, 1,
+ short_timeout(), flags), expect);
+
+ if (expect != -ETIME) {
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point, 1,
+ UINT64_MAX, flags), expect);
+ }
+
+ syncobj_destroy(fd, syncobj);
+ if (timeline != -1)
+ close(timeline);
+}
+
+static const char *test_wait_delayed_signal_desc =
+ "Verifies wait behavior on a timeline syncobj with a delayed signal"
+ " from a different thread";
+static void
+test_wait_delayed_signal(int fd, uint32_t test_flags)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint32_t flags = flags_for_test_flags(test_flags);
+ uint64_t point = 1;
+ int timeline = -1;
+ timer_t timer;
+
+ if (test_flags & WAIT_FOR_SUBMIT) {
+ timer = syncobj_trigger_delayed(fd, syncobj, point, SHORT_TIME_NSEC);
+ } else {
+ timeline = syncobj_attach_sw_sync(fd, syncobj, point);
+ timer = set_timer(timeline_inc_func, NULL,
+ timeline, SHORT_TIME_NSEC);
+ }
+
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &point, 1,
+ gettime_ns() + SHORT_TIME_NSEC * 2,
+ flags, NULL));
+
+ timer_delete(timer);
+
+ if (timeline != -1)
+ close(timeline);
+
+ syncobj_destroy(fd, syncobj);
+}
+
+static const char *test_reset_unsignaled_desc =
+ "Verifies behavior of a reset operation on an unsignaled timeline"
+ " syncobj";
+static void
+test_reset_unsignaled(int fd)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint64_t point = 1;
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
+ 1, 0, 0), -EINVAL);
+
+ syncobj_reset(fd, &syncobj, 1);
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
+ 1, 0, 0), -EINVAL);
+
+ syncobj_destroy(fd, syncobj);
+}
+
+static const char *test_reset_signaled_desc =
+ "Verifies behavior of a reset operation on a signaled timeline syncobj";
+static void
+test_reset_signaled(int fd)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint64_t point = 1;
+
+ syncobj_trigger(fd, syncobj, point);
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
+ 1, 0, 0), 0);
+
+ syncobj_reset(fd, &syncobj, 1);
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
+ 1, 0, 0), -EINVAL);
+
+ syncobj_destroy(fd, syncobj);
+}
+
+static const char *test_reset_multiple_signaled_desc =
+ "Verifies behavior of a reset operation on a list of signaled timeline"
+ " syncobjs";
+static void
+test_reset_multiple_signaled(int fd)
+{
+ uint64_t points[3] = {1, 1, 1};
+ uint32_t syncobjs[3];
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ syncobjs[i] = syncobj_create(fd, 0);
+ syncobj_trigger(fd, syncobjs[i], points[i]);
+ }
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs, points, 3, 0, 0), 0);
+
+ syncobj_reset(fd, syncobjs, 3);
+
+ for (i = 0; i < 3; i++) {
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobjs[i],
+ &points[i], 1,
+ 0, 0), -EINVAL);
+ syncobj_destroy(fd, syncobjs[i]);
+ }
+}
+
+static void
+reset_and_trigger_func(union sigval sigval)
+{
+ struct fd_handle_pair *pair = sigval.sival_ptr;
+ syncobj_reset(pair->fd, &pair->handle, 1);
+ syncobj_trigger(pair->fd, pair->handle, pair->point);
+}
+
+static const char *test_reset_during_wait_for_submit_desc =
+ "Verifies behavior of a reset operation a timeline syncobj while wait"
+ " operation is ongoing";
+static void
+test_reset_during_wait_for_submit(int fd)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint32_t flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+ struct fd_handle_pair pair;
+ uint64_t point = 1;
+ timer_t timer;
+
+ pair.fd = fd;
+ pair.handle = syncobj;
+ timer = set_timer(reset_and_trigger_func, &pair, 0, SHORT_TIME_NSEC);
+
+ /* A reset should be a no-op even if we're in the middle of a wait */
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &point, 1,
+ gettime_ns() + SHORT_TIME_NSEC * 2,
+ flags, NULL));
+
+ timer_delete(timer);
+
+ syncobj_destroy(fd, syncobj);
+}
+
+static const char *test_signal_desc =
+ "Verifies basic signaling of a timeline syncobj";
+static void
+test_signal(int fd)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint32_t flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+ uint64_t point = 1;
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
+ 1, 0, 0), -EINVAL);
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &syncobj, &point,
+ 1, 0, flags), -ETIME);
+
+ syncobj_timeline_signal(fd, &syncobj, &point, 1);
+
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &point, 1, 0, 0, NULL));
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &point, 1, 0, flags, NULL));
+
+ syncobj_destroy(fd, syncobj);
+}
+
+static const char *test_multi_wait_desc =
+ "Verifies waiting on a list of timeline syncobjs";
+static void
+test_multi_wait(int fd, uint32_t test_flags, int expect)
+{
+ uint32_t tflag, flags;
+ int i, fidx, timeline;
+ uint64_t points[5] = {
+ 1 + rand() % 1000,
+ 0, /* non timeline syncobj */
+ 1 + rand() % 1000,
+ 1 + rand() % 1000,
+ 0, /* non timeline syncobj */
+ };
+ uint32_t syncobjs[ARRAY_SIZE(points)];
+
+ for (i = 0; i < ARRAY_SIZE(points); i++)
+ syncobjs[i] = syncobj_create(fd, 0);
+
+ flags = flags_for_test_flags(test_flags);
+ test_flags &= ~(WAIT_ALL | WAIT_FOR_SUBMIT | WAIT_AVAILABLE);
+
+ for (i = 0; i < ARRAY_SIZE(points); i++) {
+ fidx = ffs(test_flags) - 1;
+ tflag = (1 << fidx);
+
+ if (test_flags & ~tflag)
+ test_flags &= ~tflag;
+
+ if (tflag & (WAIT_SUBMITTED | WAIT_SIGNALED)) {
+ timeline = syncobj_attach_sw_sync(fd, syncobjs[i],
+ points[i]);
+ }
+ if (tflag & WAIT_SIGNALED)
+ sw_sync_timeline_inc(timeline, 1);
+ }
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs,
+ points, ARRAY_SIZE(points),
+ 0, flags), expect);
+
+ igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs,
+ points, ARRAY_SIZE(points),
+ short_timeout(),
+ flags), expect);
+
+ if (expect != -ETIME) {
+ igt_assert_eq(syncobj_timeline_wait_err(fd, syncobjs,
+ points, ARRAY_SIZE(points),
+ UINT64_MAX,
+ flags), expect);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(points); i++)
+ syncobj_destroy(fd, syncobjs[i]);
+}
+
+struct wait_thread_data {
+ int fd;
+ struct drm_syncobj_timeline_wait wait;
+};
+
+static void *
+wait_thread_func(void *data)
+{
+ struct wait_thread_data *wait = data;
+ igt_assert_eq(__syncobj_timeline_wait_ioctl(wait->fd, &wait->wait), 0);
+ return NULL;
+}
+
+static const char *test_wait_snapshot_desc =
+ "Verifies waiting on a list of timeline syncobjs with different thread"
+ " for wait/signal";
+static void
+test_wait_snapshot(int fd, uint32_t test_flags)
+{
+ struct wait_thread_data wait = {};
+ uint32_t syncobjs[2];
+ uint64_t points[2] = {1, 1};
+ int timelines[3] = { -1, -1, -1 };
+ pthread_t thread;
+
+ syncobjs[0] = syncobj_create(fd, 0);
+ syncobjs[1] = syncobj_create(fd, 0);
+
+ if (!(test_flags & WAIT_FOR_SUBMIT)) {
+ timelines[0] = syncobj_attach_sw_sync(fd, syncobjs[0], points[0]);
+ timelines[1] = syncobj_attach_sw_sync(fd, syncobjs[1], points[1]);
+ }
+
+ wait.fd = fd;
+ wait.wait.handles = to_user_pointer(syncobjs);
+ wait.wait.count_handles = 2;
+ wait.wait.points = to_user_pointer(points);
+ wait.wait.timeout_nsec = short_timeout();
+ wait.wait.flags = flags_for_test_flags(test_flags);
+
+ igt_assert_eq(pthread_create(&thread, NULL, wait_thread_func, &wait), 0);
+
+ sleep_nsec(SHORT_TIME_NSEC / 5);
+
+ /* Try to fake the kernel out by triggering or partially triggering
+ * the first fence.
+ */
+ if (test_flags & WAIT_ALL) {
+ /* If it's WAIT_ALL, actually trigger it */
+ if (timelines[0] == -1)
+ syncobj_trigger(fd, syncobjs[0], points[0]);
+ else
+ sw_sync_timeline_inc(timelines[0], 1);
+ } else if (test_flags & WAIT_FOR_SUBMIT) {
+ timelines[0] = syncobj_attach_sw_sync(fd, syncobjs[0], points[0]);
+ }
+
+ sleep_nsec(SHORT_TIME_NSEC / 5);
+
+ /* Then reset it */
+ syncobj_reset(fd, &syncobjs[0], 1);
+
+ sleep_nsec(SHORT_TIME_NSEC / 5);
+
+ /* Then "submit" it in a way that will never trigger. This way, if
+ * the kernel picks up on the new fence (it shouldn't), we'll get a
+ * timeout.
+ */
+ timelines[2] = syncobj_attach_sw_sync(fd, syncobjs[0], points[0]);
+
+ sleep_nsec(SHORT_TIME_NSEC / 5);
+
+ /* Now trigger the second fence to complete the wait */
+
+ if (timelines[1] == -1)
+ syncobj_trigger(fd, syncobjs[1], points[1]);
+ else
+ sw_sync_timeline_inc(timelines[1], 1);
+
+ pthread_join(thread, NULL);
+
+ if (!(test_flags & WAIT_ALL))
+ igt_assert_eq(wait.wait.first_signaled, 1);
+
+ close(timelines[0]);
+ close(timelines[1]);
+ close(timelines[2]);
+ syncobj_destroy(fd, syncobjs[0]);
+ syncobj_destroy(fd, syncobjs[1]);
+}
+
+/* The numbers 0-7, each repeated 5x and shuffled. */
+static const unsigned shuffled_0_7_x4[] = {
+ 2, 0, 6, 1, 1, 4, 5, 2, 0, 7, 1, 7, 6, 3, 4, 5,
+ 0, 2, 7, 3, 5, 4, 0, 6, 7, 3, 2, 5, 6, 1, 4, 3,
+};
+
+enum syncobj_stage {
+ STAGE_UNSUBMITTED,
+ STAGE_SUBMITTED,
+ STAGE_SIGNALED,
+ STAGE_RESET,
+ STAGE_RESUBMITTED,
+};
+
+static const char *test_wait_complex_desc =
+ "Verifies timeline syncobj at different signal/operations stages &"
+ " between different threads.";
+static void
+test_wait_complex(int fd, uint32_t test_flags)
+{
+ struct wait_thread_data wait = {};
+ uint32_t syncobjs[8];
+ uint64_t points[8] = {1, 1, 1, 1, 1, 1, 1, 1};
+ enum syncobj_stage stage[8];
+ int i, j, timelines[8];
+ uint32_t first_signaled = -1, num_signaled = 0;
+ pthread_t thread;
+
+ for (i = 0; i < 8; i++) {
+ stage[i] = STAGE_UNSUBMITTED;
+ syncobjs[i] = syncobj_create(fd, 0);
+ }
+
+ if (test_flags & WAIT_FOR_SUBMIT) {
+ for (i = 0; i < 8; i++)
+ timelines[i] = -1;
+ } else {
+ for (i = 0; i < 8; i++)
+ timelines[i] = syncobj_attach_sw_sync(fd, syncobjs[i],
+ points[i]);
+ }
+
+ wait.fd = fd;
+ wait.wait.handles = to_user_pointer(syncobjs);
+ wait.wait.count_handles = 2;
+ wait.wait.points = to_user_pointer(points);
+ wait.wait.timeout_nsec = gettime_ns() + NSECS_PER_SEC;
+ wait.wait.flags = flags_for_test_flags(test_flags);
+
+ igt_assert_eq(pthread_create(&thread, NULL, wait_thread_func, &wait), 0);
+
+ sleep_nsec(NSECS_PER_SEC / 50);
+
+ num_signaled = 0;
+ for (j = 0; j < ARRAY_SIZE(shuffled_0_7_x4); j++) {
+ i = shuffled_0_7_x4[j];
+ igt_assert_lt(i, ARRAY_SIZE(syncobjs));
+
+ switch (stage[i]++) {
+ case STAGE_UNSUBMITTED:
+ /* We need to submit attach a fence */
+ if (!(test_flags & WAIT_FOR_SUBMIT)) {
+ /* We had to attach one up-front */
+ igt_assert_neq(timelines[i], -1);
+ break;
+ }
+ timelines[i] = syncobj_attach_sw_sync(fd, syncobjs[i],
+ points[i]);
+ break;
+
+ case STAGE_SUBMITTED:
+ /* We have a fence, trigger it */
+ igt_assert_neq(timelines[i], -1);
+ sw_sync_timeline_inc(timelines[i], 1);
+ close(timelines[i]);
+ timelines[i] = -1;
+ if (num_signaled == 0)
+ first_signaled = i;
+ num_signaled++;
+ break;
+
+ case STAGE_SIGNALED:
+ /* We're already signaled, reset */
+ syncobj_reset(fd, &syncobjs[i], 1);
+ break;
+
+ case STAGE_RESET:
+ /* We're reset, submit and don't signal */
+ timelines[i] = syncobj_attach_sw_sync(fd, syncobjs[i],
+ points[i]);
+ break;
+
+ case STAGE_RESUBMITTED:
+ igt_assert(!"Should not reach this stage");
+ break;
+ }
+
+ if (test_flags & WAIT_ALL) {
+ if (num_signaled == ARRAY_SIZE(syncobjs))
+ break;
+ } else {
+ if (num_signaled > 0)
+ break;
+ }
+
+ sleep_nsec(NSECS_PER_SEC / 100);
+ }
+
+ pthread_join(thread, NULL);
+
+ if (test_flags & WAIT_ALL) {
+ igt_assert_eq(num_signaled, ARRAY_SIZE(syncobjs));
+ } else {
+ igt_assert_eq(num_signaled, 1);
+ igt_assert_eq(wait.wait.first_signaled, first_signaled);
+ }
+
+ for (i = 0; i < 8; i++) {
+ close(timelines[i]);
+ syncobj_destroy(fd, syncobjs[i]);
+ }
+}
+
+static const char *test_wait_interrupted_desc =
+ "Verifies timeline syncobj waits interaction with signals.";
+static void
+test_wait_interrupted(int fd, uint32_t test_flags)
+{
+ struct drm_syncobj_timeline_wait wait = {};
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint64_t point = 1;
+ int timeline;
+
+ wait.handles = to_user_pointer(&syncobj);
+ wait.points = to_user_pointer(&point);
+ wait.count_handles = 1;
+ wait.flags = flags_for_test_flags(test_flags);
+
+ if (test_flags & WAIT_FOR_SUBMIT) {
+ wait.timeout_nsec = short_timeout();
+ igt_while_interruptible(true)
+ igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -ETIME);
+ }
+
+ timeline = syncobj_attach_sw_sync(fd, syncobj, point);
+
+ wait.timeout_nsec = short_timeout();
+ igt_while_interruptible(true)
+ igt_assert_eq(__syncobj_timeline_wait_ioctl(fd, &wait), -ETIME);
+
+ syncobj_destroy(fd, syncobj);
+ close(timeline);
+}
+
+static bool
+has_syncobj_timeline_wait(int fd)
+{
+ struct drm_syncobj_timeline_wait wait = {};
+ uint32_t handle = 0;
+ uint64_t value;
+ int ret;
+
+ if (drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &value))
+ return false;
+ if (!value)
+ return false;
+
+ /* Try waiting for zero sync objects should fail with EINVAL */
+ wait.count_handles = 1;
+ wait.handles = to_user_pointer(&handle);
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, &wait);
+ return ret == -1 && errno == ENOENT;
+}
+
+igt_main
+{
+ int fd = -1;
+
+ igt_fixture {
+ fd = drm_open_driver(DRIVER_ANY);
+ igt_require(has_syncobj_timeline_wait(fd));
+ igt_require_sw_sync();
+ }
+
+ igt_describe(test_wait_bad_flags_desc);
+ igt_subtest("invalid-wait-bad-flags")
+ test_wait_bad_flags(fd);
+
+ igt_describe(test_wait_zero_handles_desc);
+ igt_subtest("invalid-wait-zero-handles")
+ test_wait_zero_handles(fd);
+
+ igt_describe(test_wait_illegal_handle_desc);
+ igt_subtest("invalid-wait-illegal-handle")
+ test_wait_illegal_handle(fd);
+
+ igt_describe(test_query_zero_handles_desc);
+ igt_subtest("invalid-query-zero-handles")
+ test_query_zero_handles(fd);
+
+ igt_describe(test_query_illegal_handle_desc);
+ igt_subtest("invalid-query-illegal-handle")
+ test_query_illegal_handle(fd);
+
+ igt_describe(test_query_one_illegal_handle_desc);
+ igt_subtest("invalid-query-one-illegal-handle")
+ test_query_one_illegal_handle(fd);
+
+ igt_describe(test_query_bad_pad_desc);
+ igt_subtest("invalid-query-bad-pad")
+ test_query_bad_pad(fd);
+
+ igt_describe(test_signal_zero_handles_desc);
+ igt_subtest("invalid-signal-zero-handles")
+ test_signal_zero_handles(fd);
+
+ igt_describe(test_signal_illegal_handle_desc);
+ igt_subtest("invalid-signal-illegal-handle")
+ test_signal_illegal_handle(fd);
+
+ igt_subtest("invalid-signal-illegal-point")
+ test_signal_illegal_point(fd);
+
+ igt_describe(test_signal_one_illegal_handle_desc);
+ igt_subtest("invalid-signal-one-illegal-handle")
+ test_signal_one_illegal_handle(fd);
+
+ igt_describe(test_signal_bad_pad_desc);
+ igt_subtest("invalid-signal-bad-pad")
+ test_signal_bad_pad(fd);
+
+ igt_describe(test_signal_array_desc);
+ igt_subtest("signal-array")
+ test_signal_array(fd);
+
+ igt_describe(test_transfer_illegal_handle_desc);
+ igt_subtest("invalid-transfer-illegal-handle")
+ test_transfer_illegal_handle(fd);
+
+ igt_describe(test_transfer_bad_pad_desc);
+ igt_subtest("invalid-transfer-bad-pad")
+ test_transfer_bad_pad(fd);
+
+ for (unsigned flags = 0; flags < WAIT_FLAGS_MAX; flags++) {
+ int err;
+
+ /* Only one wait mode for single-wait tests */
+ if (__builtin_popcount(flags & (WAIT_UNSUBMITTED |
+ WAIT_SUBMITTED |
+ WAIT_SIGNALED)) != 1)
+ continue;
+
+ if ((flags & WAIT_UNSUBMITTED) && !(flags & WAIT_FOR_SUBMIT))
+ err = -EINVAL;
+ else if (!(flags & WAIT_SIGNALED) && !((flags & WAIT_SUBMITTED) && (flags & WAIT_AVAILABLE)))
+ err = -ETIME;
+ else
+ err = 0;
+
+ igt_describe(test_signal_wait_desc);
+ igt_subtest_f("%ssingle-wait%s%s%s%s%s%s",
+ err == -EINVAL ? "invalid-" : err == -ETIME ? "etime-" : "",
+ (flags & WAIT_ALL) ? "-all" : "",
+ (flags & WAIT_FOR_SUBMIT) ? "-for-submit" : "",
+ (flags & WAIT_AVAILABLE) ? "-available" : "",
+ (flags & WAIT_UNSUBMITTED) ? "-unsubmitted" : "",
+ (flags & WAIT_SUBMITTED) ? "-submitted" : "",
+ (flags & WAIT_SIGNALED) ? "-signaled" : "")
+ test_single_wait(fd, flags, err);
+ }
+
+ igt_describe(test_wait_delayed_signal_desc);
+ igt_subtest("wait-delayed-signal")
+ test_wait_delayed_signal(fd, 0);
+
+ igt_describe(test_wait_delayed_signal_desc);
+ igt_subtest("wait-for-submit-delayed-submit")
+ test_wait_delayed_signal(fd, WAIT_FOR_SUBMIT);
+
+ igt_describe(test_wait_delayed_signal_desc);
+ igt_subtest("wait-all-delayed-signal")
+ test_wait_delayed_signal(fd, WAIT_ALL);
+
+ igt_describe(test_wait_delayed_signal_desc);
+ igt_subtest("wait-all-for-submit-delayed-submit")
+ test_wait_delayed_signal(fd, WAIT_ALL | WAIT_FOR_SUBMIT);
+
+ igt_describe(test_reset_unsignaled_desc);
+ igt_subtest("reset-unsignaled")
+ test_reset_unsignaled(fd);
+
+ igt_describe(test_reset_signaled_desc);
+ igt_subtest("reset-signaled")
+ test_reset_signaled(fd);
+
+ igt_describe(test_reset_multiple_signaled_desc);
+ igt_subtest("reset-multiple-signaled")
+ test_reset_multiple_signaled(fd);
+
+ igt_describe(test_reset_during_wait_for_submit_desc);
+ igt_subtest("reset-during-wait-for-submit")
+ test_reset_during_wait_for_submit(fd);
+
+ igt_describe(test_signal_desc);
+ igt_subtest("signal")
+ test_signal(fd);
+
+ for (unsigned flags = 0; flags < WAIT_FLAGS_MAX; flags++) {
+ int err;
+
+ /* At least one wait mode for multi-wait tests */
+ if (!(flags & (WAIT_UNSUBMITTED |
+ WAIT_SUBMITTED |
+ WAIT_SIGNALED)))
+ continue;
+
+ err = 0;
+ if ((flags & WAIT_UNSUBMITTED) && !(flags & WAIT_FOR_SUBMIT)) {
+ err = -EINVAL;
+ } else if (flags & WAIT_ALL) {
+ if (flags & (WAIT_UNSUBMITTED | WAIT_SUBMITTED))
+ err = -ETIME;
+ if (!(flags & WAIT_UNSUBMITTED) && (flags & WAIT_SUBMITTED) && (flags & WAIT_AVAILABLE))
+ err = 0;
+ } else {
+ if (!(flags & WAIT_SIGNALED) && !((flags & WAIT_SUBMITTED) && (flags & WAIT_AVAILABLE)))
+ err = -ETIME;
+ }
+
+ igt_describe(test_multi_wait_desc);
+ igt_subtest_f("%smulti-wait%s%s%s%s%s%s",
+ err == -EINVAL ? "invalid-" : err == -ETIME ? "etime-" : "",
+ (flags & WAIT_ALL) ? "-all" : "",
+ (flags & WAIT_FOR_SUBMIT) ? "-for-submit" : "",
+ (flags & WAIT_AVAILABLE) ? "-available" : "",
+ (flags & WAIT_UNSUBMITTED) ? "-unsubmitted" : "",
+ (flags & WAIT_SUBMITTED) ? "-submitted" : "",
+ (flags & WAIT_SIGNALED) ? "-signaled" : "")
+ test_multi_wait(fd, flags, err);
+ }
+
+ igt_describe(test_wait_snapshot_desc);
+ igt_subtest("wait-any-snapshot")
+ test_wait_snapshot(fd, 0);
+
+ igt_describe(test_wait_snapshot_desc);
+ igt_subtest("wait-all-snapshot")
+ test_wait_snapshot(fd, WAIT_ALL);
+
+ igt_describe(test_wait_snapshot_desc);
+ igt_subtest("wait-for-submit-snapshot")
+ test_wait_snapshot(fd, WAIT_FOR_SUBMIT);
+
+ igt_describe(test_wait_snapshot_desc);
+ igt_subtest("wait-all-for-submit-snapshot")
+ test_wait_snapshot(fd, WAIT_ALL | WAIT_FOR_SUBMIT);
+
+ igt_describe(test_wait_complex_desc);
+ igt_subtest("wait-any-complex")
+ test_wait_complex(fd, 0);
+
+ igt_describe(test_wait_complex_desc);
+ igt_subtest("wait-all-complex")
+ test_wait_complex(fd, WAIT_ALL);
+
+ igt_describe(test_wait_complex_desc);
+ igt_subtest("wait-for-submit-complex")
+ test_wait_complex(fd, WAIT_FOR_SUBMIT);
+
+ igt_describe(test_wait_complex_desc);
+ igt_subtest("wait-all-for-submit-complex")
+ test_wait_complex(fd, WAIT_ALL | WAIT_FOR_SUBMIT);
+
+ igt_describe(test_wait_interrupted_desc);
+ igt_subtest("wait-any-interrupted")
+ test_wait_interrupted(fd, 0);
+
+ igt_describe(test_wait_interrupted_desc);
+ igt_subtest("wait-all-interrupted")
+ test_wait_interrupted(fd, WAIT_ALL);
+}
--
2.28.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [igt-dev] [PATCH i-g-t 3/5] tests/syncobj_timeline: add more timeline tests
2020-07-31 13:41 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 2/5] igt: add timeline test cases Lionel Landwerlin
@ 2020-07-31 13:41 ` Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 4/5] tests/i915/exec_fence: add timeline fence tests Lionel Landwerlin
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2020-07-31 13:41 UTC (permalink / raw)
To: igt-dev
Including ordering tests and 32bit limit.
v2: add point 0 signaling test (Lionel)
v3: Use READ_ONCE() in thread checker (Chris)
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
lib/igt_syncobj.c | 73 ++++----
lib/igt_syncobj.h | 3 +
tests/syncobj_timeline.c | 387 +++++++++++++++++++++++++++++++++++++++
3 files changed, 426 insertions(+), 37 deletions(-)
diff --git a/lib/igt_syncobj.c b/lib/igt_syncobj.c
index b211dfef..a24ed10b 100644
--- a/lib/igt_syncobj.c
+++ b/lib/igt_syncobj.c
@@ -459,17 +459,19 @@ syncobj_timeline_query(int fd, uint32_t *handles, uint64_t *points,
}
static int
-__syncobj_binary_to_timeline(int fd, uint32_t timeline_handle,
- uint64_t point, uint32_t binary_handle)
+__syncobj_transfer(int fd,
+ uint32_t handle_dst, uint64_t point_dst,
+ uint32_t handle_src, uint64_t point_src,
+ uint32_t flags)
{
struct drm_syncobj_transfer args;
int ret;
- args.src_handle = binary_handle;
- args.dst_handle = timeline_handle;
- args.src_point = 0;
- args.dst_point = point;
- args.flags = 0;
+ args.src_handle = handle_src;
+ args.dst_handle = handle_dst;
+ args.src_point = point_src;
+ args.dst_point = point_dst;
+ args.flags = flags;
args.pad = 0;
ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
if (ret) {
@@ -495,33 +497,9 @@ void
syncobj_binary_to_timeline(int fd, uint32_t timeline_handle,
uint64_t point, uint32_t binary_handle)
{
- igt_assert_eq(__syncobj_binary_to_timeline(fd, timeline_handle, point,
- binary_handle), 0);
-}
-
-static int
-__syncobj_timeline_to_binary(int fd, uint32_t binary_handle,
- uint32_t timeline_handle,
- uint64_t point,
- uint32_t flags)
-{
- struct drm_syncobj_transfer args;
- int ret;
-
- args.dst_handle = binary_handle;
- args.src_handle = timeline_handle;
- args.dst_point = 0;
- args.src_point = point;
- args.flags = flags;
- args.pad = 0;
- ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &args);
- if (ret) {
- ret = -errno;
- igt_assert(ret);
- }
-
- errno = 0;
- return ret;
+ igt_assert_eq(__syncobj_transfer(fd,
+ timeline_handle, point,
+ binary_handle, 0, 0), 0);
}
/**
@@ -540,7 +518,28 @@ syncobj_timeline_to_binary(int fd, uint32_t binary_handle,
uint64_t point,
uint32_t flags)
{
- igt_assert_eq(__syncobj_timeline_to_binary(fd, binary_handle,
- timeline_handle, point,
- flags), 0);
+ igt_assert_eq(__syncobj_transfer(fd,
+ binary_handle, 0,
+ timeline_handle, point,
+ flags), 0);
+}
+
+/**
+ * syncobj_timeline_to_timeline:
+ * @fd: The DRM file descriptor.
+ * @timeline_src: A timeline syncobj handle
+ * @timeline_dst: A timeline syncobj handle
+ * @point_src: A point on the source timeline syncobj
+ * @point_dst: A point on the destination timeline syncobj
+ *
+ * query a set of syncobjs.
+ */
+void
+syncobj_timeline_to_timeline(int fd,
+ uint64_t timeline_dst, uint32_t point_dst,
+ uint64_t timeline_src, uint32_t point_src)
+{
+ igt_assert_eq(__syncobj_transfer(fd,
+ timeline_dst, point_dst,
+ timeline_src, point_src, 0), 0);
}
diff --git a/lib/igt_syncobj.h b/lib/igt_syncobj.h
index 20f1f18f..e6725671 100644
--- a/lib/igt_syncobj.h
+++ b/lib/igt_syncobj.h
@@ -60,6 +60,9 @@ void syncobj_timeline_to_binary(int fd, uint32_t binary_handle,
uint32_t timeline_handle,
uint64_t point,
uint32_t flags);
+void syncobj_timeline_to_timeline(int fd,
+ uint64_t timeline_dst, uint32_t point_dst,
+ uint64_t timeline_src, uint32_t point_src);
void syncobj_timeline_signal(int fd, uint32_t *handles, uint64_t *points,
uint32_t count);
diff --git a/tests/syncobj_timeline.c b/tests/syncobj_timeline.c
index 82fc08aa..319dc1bd 100644
--- a/tests/syncobj_timeline.c
+++ b/tests/syncobj_timeline.c
@@ -406,6 +406,29 @@ test_transfer_bad_pad(int fd)
igt_assert(ret == -1 && errno == EINVAL);
}
+static const char *test_transfer_nonexistent_point_desc =
+ "Verifies that transfering a point from a syncobj timeline is to"
+ " another point in the same timeline works";
+static void
+test_transfer_nonexistent_point(int fd)
+{
+ struct drm_syncobj_transfer arg = {};
+ uint32_t handle = syncobj_create(fd, 0);
+ uint64_t value = 63;
+ int ret;
+
+ syncobj_timeline_signal(fd, &handle, &value, 1);
+
+ arg.src_handle = handle;
+ arg.dst_handle = handle;
+ arg.src_point = value; /* Point doesn't exist */
+ arg.dst_point = value + 11;
+ ret = igt_ioctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, &arg);
+ igt_assert(ret == 0);
+
+ syncobj_destroy(fd, handle);
+}
+
#define WAIT_FOR_SUBMIT (1 << 0)
#define WAIT_ALL (1 << 1)
#define WAIT_AVAILABLE (1 << 2)
@@ -414,6 +437,53 @@ test_transfer_bad_pad(int fd)
#define WAIT_SIGNALED (1 << 5)
#define WAIT_FLAGS_MAX (1 << 6) - 1
+static const char *test_transfer_point_desc =
+ "Verifies that transfering a point from a syncobj timeline is to"
+ " another point in the same timeline works for signal/wait operations";
+static void
+test_transfer_point(int fd)
+{
+ int timeline = sw_sync_timeline_create();
+ uint32_t handle = syncobj_create(fd, 0);
+ uint64_t value;
+
+ {
+ int sw_fence = sw_sync_timeline_create_fence(timeline, 1);
+ uint32_t tmp_syncobj = syncobj_create(fd, 0);
+
+ syncobj_import_sync_file(fd, tmp_syncobj, sw_fence);
+ syncobj_binary_to_timeline(fd, handle, 1, tmp_syncobj);
+ close(sw_fence);
+ syncobj_destroy(fd, tmp_syncobj);
+ }
+
+ syncobj_timeline_query(fd, &handle, &value, 1);
+ igt_assert_eq(value, 0);
+
+ value = 1;
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &handle, &value,
+ 1, 0, WAIT_ALL), -ETIME);
+
+ sw_sync_timeline_inc(timeline, 1);
+
+ syncobj_timeline_query(fd, &handle, &value, 1);
+ igt_assert_eq(value, 1);
+
+ igt_assert(syncobj_timeline_wait(fd, &handle, &value,
+ 1, 0, WAIT_ALL, NULL));
+
+ value = 2;
+ syncobj_timeline_signal(fd, &handle, &value, 1);
+
+ syncobj_timeline_to_timeline(fd, handle, 3, handle, 2);
+
+ syncobj_timeline_query(fd, &handle, &value, 1);
+ igt_assert_eq(value, 3);
+
+ syncobj_destroy(fd, handle);
+ close(timeline);
+}
+
static uint32_t
flags_for_test_flags(uint32_t test_flags)
{
@@ -619,6 +689,24 @@ test_signal(int fd)
syncobj_destroy(fd, syncobj);
}
+static const char *test_signal_point_0_desc =
+ "Verifies that signaling point 0 of a timline syncobj works with both"
+ " timeline & legacy wait operations";
+static void
+test_signal_point_0(int fd)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint32_t flags = DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT;
+ uint64_t point = 0;
+
+ syncobj_timeline_signal(fd, &syncobj, &point, 1);
+
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &point, 1, 0, 0, NULL));
+ igt_assert(syncobj_wait(fd, &syncobj, 1, 0, flags, NULL));
+
+ syncobj_destroy(fd, syncobj);
+}
+
static const char *test_multi_wait_desc =
"Verifies waiting on a list of timeline syncobjs";
static void
@@ -921,6 +1009,273 @@ test_wait_interrupted(int fd, uint32_t test_flags)
close(timeline);
}
+const char *test_host_signal_points_desc =
+ "Verifies that as we signal points from the host, the syncobj timeline"
+ " value increments and that waits for submits/signals works properly.";
+static void
+test_host_signal_points(int fd)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint64_t value = 0;
+ int i;
+
+ for (i = 0; i < 100; i++) {
+ uint64_t query_value = 0;
+
+ value += rand();
+
+ syncobj_timeline_signal(fd, &syncobj, &value, 1);
+
+ syncobj_timeline_query(fd, &syncobj, &query_value, 1);
+ igt_assert_eq(query_value, value);
+
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &query_value,
+ 1, 0, WAIT_FOR_SUBMIT, NULL));
+
+ query_value -= 1;
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &query_value,
+ 1, 0, WAIT_ALL, NULL));
+ }
+
+ syncobj_destroy(fd, syncobj);
+}
+
+const char *test_device_signal_unordered_desc =
+ "Verifies that a device signaling fences out of order on the timeline"
+ " still increments the timeline monotonically and that waits work"
+ " properly.";
+static void
+test_device_signal_unordered(int fd)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ int point_indices[] = { 0, 2, 1, 4, 3 };
+ bool signaled[ARRAY_SIZE(point_indices)] = {};
+ int fences[ARRAY_SIZE(point_indices)];
+ int timeline = sw_sync_timeline_create();
+ uint64_t value = 0;
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(fences); i++) {
+ fences[point_indices[i]] = sw_sync_timeline_create_fence(timeline, i + 1);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(fences); i++) {
+ uint32_t tmp_syncobj = syncobj_create(fd, 0);
+
+ syncobj_import_sync_file(fd, tmp_syncobj, fences[i]);
+ syncobj_binary_to_timeline(fd, syncobj, i + 1, tmp_syncobj);
+ syncobj_destroy(fd, tmp_syncobj);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(fences); i++) {
+ uint64_t query_value = 0;
+ uint64_t min_value = 0;
+
+ sw_sync_timeline_inc(timeline, 1);
+
+ signaled[point_indices[i]] = true;
+
+ /*
+ * Compute a minimum value of the timeline based of
+ * the smallest signaled point.
+ */
+ for (j = 0; j < ARRAY_SIZE(signaled); j++) {
+ if (!signaled[j])
+ break;
+ min_value = j;
+ }
+
+ syncobj_timeline_query(fd, &syncobj, &query_value, 1);
+ igt_assert(query_value >= min_value);
+ igt_assert(query_value >= value);
+
+ igt_debug("signaling point %i, timeline value = %" PRIu64 "\n",
+ point_indices[i] + 1, query_value);
+
+ value = max(query_value, value);
+
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &query_value,
+ 1, 0, WAIT_FOR_SUBMIT, NULL));
+
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &query_value,
+ 1, 0, WAIT_ALL, NULL));
+ }
+
+ for (i = 0; i < ARRAY_SIZE(fences); i++)
+ close(fences[i]);
+
+ syncobj_destroy(fd, syncobj);
+ close(timeline);
+}
+
+const char *test_device_submit_unordered_desc =
+ "Verifies that submitting out of order doesn't break the timeline.";
+static void
+test_device_submit_unordered(int fd)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ uint64_t points[] = { 1, 5, 3, 6, 7 };
+ int timeline = sw_sync_timeline_create();
+ uint64_t query_value;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(points); i++) {
+ int fence = sw_sync_timeline_create_fence(timeline, i + 1);
+ uint32_t tmp_syncobj = syncobj_create(fd, 0);
+
+ syncobj_import_sync_file(fd, tmp_syncobj, fence);
+ syncobj_binary_to_timeline(fd, syncobj, points[i], tmp_syncobj);
+ close(fence);
+ syncobj_destroy(fd, tmp_syncobj);
+ }
+
+ /*
+ * Signal points 1, 5 & 3. There are no other points <= 5 so
+ * waiting on 5 should return immediately for submission &
+ * signaling.
+ */
+ sw_sync_timeline_inc(timeline, 3);
+
+ syncobj_timeline_query(fd, &syncobj, &query_value, 1);
+ igt_assert_eq(query_value, 5);
+
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &query_value,
+ 1, 0, WAIT_FOR_SUBMIT, NULL));
+
+ igt_assert(syncobj_timeline_wait(fd, &syncobj, &query_value,
+ 1, 0, WAIT_ALL, NULL));
+
+ syncobj_destroy(fd, syncobj);
+ close(timeline);
+}
+
+const char *test_host_signal_ordered_desc =
+ "Verifies that the host signaling fences out of order on the timeline"
+ " still increments the timeline monotonically and that waits work"
+ " properly.";
+static void
+test_host_signal_ordered(int fd)
+{
+ uint32_t syncobj = syncobj_create(fd, 0);
+ int timeline = sw_sync_timeline_create();
+ uint64_t host_signal_value = 8, query_value;
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ int fence = sw_sync_timeline_create_fence(timeline, i + 1);
+ uint32_t tmp_syncobj = syncobj_create(fd, 0);
+
+ syncobj_import_sync_file(fd, tmp_syncobj, fence);
+ syncobj_binary_to_timeline(fd, syncobj, i + 1, tmp_syncobj);
+ syncobj_destroy(fd, tmp_syncobj);
+ close(fence);
+ }
+
+ sw_sync_timeline_inc(timeline, 3);
+
+ syncobj_timeline_query(fd, &syncobj, &query_value, 1);
+ igt_assert_eq(query_value, 3);
+
+ syncobj_timeline_signal(fd, &syncobj, &host_signal_value, 1);
+
+ syncobj_timeline_query(fd, &syncobj, &query_value, 1);
+ igt_assert_eq(query_value, 3);
+
+ sw_sync_timeline_inc(timeline, 5);
+
+ syncobj_timeline_query(fd, &syncobj, &query_value, 1);
+ igt_assert_eq(query_value, 8);
+
+ syncobj_destroy(fd, syncobj);
+ close(timeline);
+}
+
+struct checker_thread_data {
+ int fd;
+ uint32_t syncobj;
+ bool running;
+ bool started;
+};
+
+static void *
+checker_thread_func(void *_data)
+{
+ struct checker_thread_data *data = _data;
+ uint64_t value, last_value = 0;
+
+ while (READ_ONCE(data->running)) {
+ syncobj_timeline_query(data->fd, &data->syncobj, &value, 1);
+
+ data->started = true;
+
+ igt_assert(last_value <= value);
+ last_value = value;
+ }
+
+ return NULL;
+}
+
+const char *test_32bits_limit_desc =
+ "Verifies that signaling around the int32_t limit. For compatibility"
+ " reason, the handling of seqnos in the dma-fences can consider a seqnoA"
+ " is prior seqnoB even though seqnoA > seqnoB.";
+/*
+ * Fixed in kernel commit :
+ *
+ * commit b312d8ca3a7cebe19941d969a51f2b7f899b81e2
+ * Author: Christian König <christian.koenig@amd.com>
+ * Date: Wed Nov 14 16:11:06 2018 +0100
+ *
+ * dma-buf: make fence sequence numbers 64 bit v2
+ *
+ */
+static void
+test_32bits_limit(int fd)
+{
+ struct checker_thread_data thread_data = {
+ .fd = fd,
+ .syncobj = syncobj_create(fd, 0),
+ .running = true,
+ .started = false,
+ };
+ int timeline = sw_sync_timeline_create();
+ uint64_t limit_diff = (1ull << 31) - 1;
+ uint64_t points[] = { 1, 5, limit_diff + 5, limit_diff + 6, limit_diff * 2, };
+ pthread_t thread;
+ uint64_t value, last_value;
+ int i;
+
+ igt_assert_eq(pthread_create(&thread, NULL, checker_thread_func, &thread_data), 0);
+
+ while (!thread_data.started);
+
+ for (i = 0; i < ARRAY_SIZE(points); i++) {
+ int fence = sw_sync_timeline_create_fence(timeline, i + 1);
+ uint32_t tmp_syncobj = syncobj_create(fd, 0);
+
+ syncobj_import_sync_file(fd, tmp_syncobj, fence);
+ syncobj_binary_to_timeline(fd, thread_data.syncobj, points[i], tmp_syncobj);
+ close(fence);
+ syncobj_destroy(fd, tmp_syncobj);
+ }
+
+ last_value = 0;
+ for (i = 0; i < ARRAY_SIZE(points); i++) {
+ sw_sync_timeline_inc(timeline, 1);
+
+ syncobj_timeline_query(fd, &thread_data.syncobj, &value, 1);
+ igt_assert(last_value <= value);
+
+ last_value = value;
+ }
+
+ thread_data.running = false;
+ pthread_join(thread, NULL);
+
+ syncobj_destroy(fd, thread_data.syncobj);
+ close(timeline);
+}
+
static bool
has_syncobj_timeline_wait(int fd)
{
@@ -1010,6 +1365,14 @@ igt_main
igt_subtest("invalid-transfer-bad-pad")
test_transfer_bad_pad(fd);
+ igt_describe(test_transfer_nonexistent_point_desc);
+ igt_subtest("invalid-transfer-non-existent-point")
+ test_transfer_nonexistent_point(fd);
+
+ igt_describe(test_transfer_point_desc);
+ igt_subtest("transfer-timeline-point")
+ test_transfer_point(fd);
+
for (unsigned flags = 0; flags < WAIT_FLAGS_MAX; flags++) {
int err;
@@ -1074,6 +1437,10 @@ igt_main
igt_subtest("signal")
test_signal(fd);
+ igt_describe(test_signal_point_0_desc);
+ igt_subtest("signal-point-0")
+ test_signal_point_0(fd);
+
for (unsigned flags = 0; flags < WAIT_FLAGS_MAX; flags++) {
int err;
@@ -1147,4 +1514,24 @@ igt_main
igt_describe(test_wait_interrupted_desc);
igt_subtest("wait-all-interrupted")
test_wait_interrupted(fd, WAIT_ALL);
+
+ igt_describe(test_host_signal_points_desc);
+ igt_subtest("host-signal-points")
+ test_host_signal_points(fd);
+
+ igt_describe(test_device_signal_unordered_desc);
+ igt_subtest("device-signal-unordered")
+ test_device_signal_unordered(fd);
+
+ igt_describe(test_device_submit_unordered_desc);
+ igt_subtest("device-submit-unordered")
+ test_device_submit_unordered(fd);
+
+ igt_describe(test_host_signal_ordered_desc);
+ igt_subtest("host-signal-ordered")
+ test_host_signal_ordered(fd);
+
+ igt_describe(test_32bits_limit_desc);
+ igt_subtest("32bits-limit")
+ test_32bits_limit(fd);
}
--
2.28.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [igt-dev] [PATCH i-g-t 4/5] tests/i915/exec_fence: add timeline fence tests
2020-07-31 13:41 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
` (2 preceding siblings ...)
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 3/5] tests/syncobj_timeline: add more timeline tests Lionel Landwerlin
@ 2020-07-31 13:41 ` Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 5/5] tests/i915/gem_exec_fence: add engine chaining tests Lionel Landwerlin
` (2 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2020-07-31 13:41 UTC (permalink / raw)
To: igt-dev
We can now give a tuple (handle, point_value) for timeline semaphores.
v2: Fix up syncobj-timeline-repeat test (Lionel)
Update following kernel rename
v3: Add more ordering tests for syncobj/buffer handle state (Chris)
v4: Rebase
Drop gem_context_set_all_engines()
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
tests/i915/gem_exec_fence.c | 684 ++++++++++++++++++++++++++++++++++++
1 file changed, 684 insertions(+)
diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 863386c5..97439b4b 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -1580,6 +1580,646 @@ static void test_syncobj_channel(int fd)
syncobj_destroy(fd, syncobj[i]);
}
+static bool has_syncobj_timeline(int fd)
+{
+ struct drm_get_cap cap = { .capability = DRM_CAP_SYNCOBJ_TIMELINE };
+ ioctl(fd, DRM_IOCTL_GET_CAP, &cap);
+ return cap.value;
+}
+
+static bool exec_has_timeline_fences(int fd)
+{
+ struct drm_i915_getparam gp;
+ int value = 0;
+
+ memset(&gp, 0, sizeof(gp));
+ gp.param = I915_PARAM_HAS_EXEC_TIMELINE_FENCES;
+ gp.value = &value;
+
+ ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp));
+ errno = 0;
+
+ return value;
+}
+
+static const char *test_invalid_timeline_fence_array_desc =
+ "Verifies invalid execbuf parameters in"
+ " drm_i915_gem_execbuffer_ext_timeline_fences are rejected";
+static void test_invalid_timeline_fence_array(int fd)
+{
+ const uint32_t bbe = MI_BATCH_BUFFER_END;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+ struct drm_i915_gem_exec_fence fence;
+ uint64_t value;
+ void *ptr;
+
+ /* create an otherwise valid execbuf */
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ gem_execbuf(fd, &execbuf);
+
+ /* Invalid num_cliprects value */
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 1;
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+ fence.handle = syncobj_create(fd, 0);
+ fence.flags = I915_EXEC_FENCE_SIGNAL;
+ value = 1;
+
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+
+ /* Invalid fence array & i915 ext */
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 0;
+ execbuf.flags = I915_EXEC_FENCE_ARRAY | I915_EXEC_USE_EXTENSIONS;
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+ syncobj_create(fd, fence.handle);
+
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+
+ /* Invalid handles_ptr */
+ value = 1;
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = -1;
+ timeline_fences.values_ptr = to_user_pointer(&value);
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
+
+ /* Invalid values_ptr */
+ value = 1;
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = -1;
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
+
+ /* Invalid syncobj handle */
+ memset(&fence, 0, sizeof(fence));
+ fence.handle = 0;
+ fence.flags = I915_EXEC_FENCE_WAIT;
+ value = 1;
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+ /* Invalid syncobj timeline point */
+ memset(&fence, 0, sizeof(fence));
+ fence.handle = syncobj_create(fd, 0);
+ fence.flags = I915_EXEC_FENCE_WAIT;
+ value = 1;
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+ syncobj_destroy(fd, fence.handle);
+
+ /* Invalid handles_ptr */
+ ptr = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+ igt_assert(ptr != MAP_FAILED);
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(ptr);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+ do_or_die(mprotect(ptr, 4096, PROT_READ));
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+ do_or_die(mprotect(ptr, 4096, PROT_NONE));
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
+
+ munmap(ptr, 4096);
+
+ /* Invalid values_ptr */
+ ptr = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+ igt_assert(ptr != MAP_FAILED);
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(ptr);
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+ do_or_die(mprotect(ptr, 4096, PROT_READ));
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -ENOENT);
+
+ do_or_die(mprotect(ptr, 4096, PROT_NONE));
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EFAULT);
+
+ munmap(ptr, 4096);
+}
+
+static const char *test_syncobj_timeline_unused_fence_desc =
+ "Verifies that a timeline syncobj passed into"
+ " drm_i915_gem_execbuffer_ext_timeline_fences but with no signal/wait"
+ " flag is left untouched";
+static void test_syncobj_timeline_unused_fence(int fd)
+{
+ const uint32_t bbe = MI_BATCH_BUFFER_END;
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+ struct drm_i915_gem_exec_fence fence = {
+ .handle = syncobj_create(fd, 0),
+ };
+ igt_spin_t *spin = igt_spin_new(fd);
+ uint64_t value = 1;
+
+ /* sanity check our syncobj_to_sync_file interface */
+ igt_assert_eq(__syncobj_to_sync_file(fd, 0), -ENOENT);
+
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 0;
+
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+ gem_execbuf(fd, &execbuf);
+
+ /* no flags, the fence isn't created */
+ igt_assert_eq(__syncobj_to_sync_file(fd, fence.handle), -EINVAL);
+ igt_assert(gem_bo_busy(fd, obj.handle));
+
+ gem_close(fd, obj.handle);
+ syncobj_destroy(fd, fence.handle);
+
+ igt_spin_free(fd, spin);
+}
+
+static const char *test_syncobj_timeline_invalid_wait_desc =
+ "Verifies that submitting an execbuf with a wait on a timeline syncobj"
+ " point that does not exists is rejected";
+static void test_syncobj_timeline_invalid_wait(int fd)
+{
+ const uint32_t bbe = MI_BATCH_BUFFER_END;
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+ struct drm_i915_gem_exec_fence fence = {
+ .handle = syncobj_create(fd, 0),
+ };
+ uint64_t value = 1;
+
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 0;
+
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+ /* waiting before the fence point 1 is set is invalid */
+ fence.flags = I915_EXEC_FENCE_WAIT;
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+ /* Now set point 1. */
+ fence.flags = I915_EXEC_FENCE_SIGNAL;
+ gem_execbuf(fd, &execbuf);
+
+ /* waiting before the fence point 2 is set is invalid */
+ value = 2;
+ fence.flags = I915_EXEC_FENCE_WAIT;
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+ gem_close(fd, obj.handle);
+ syncobj_destroy(fd, fence.handle);
+}
+
+static const char *test_syncobj_timeline_invalid_flags_desc =
+ "Verifies that invalid fence flags in"
+ " drm_i915_gem_execbuffer_ext_timeline_fences are rejected";
+static void test_syncobj_timeline_invalid_flags(int fd)
+{
+ const uint32_t bbe = MI_BATCH_BUFFER_END;
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+ struct drm_i915_gem_exec_fence fence = {
+ .handle = syncobj_create(fd, 0),
+ };
+ uint64_t value = 1;
+
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 0;
+
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+ /* set all flags to hit an invalid one */
+ fence.flags = ~0;
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+ gem_close(fd, obj.handle);
+ syncobj_destroy(fd, fence.handle);
+}
+
+static uint64_t
+gettime_ns(void)
+{
+ struct timespec current;
+ clock_gettime(CLOCK_MONOTONIC, ¤t);
+ return (uint64_t)current.tv_sec * NSEC_PER_SEC + current.tv_nsec;
+}
+
+static const char *test_syncobj_timeline_signal_desc =
+ "Verifies proper signaling of a timeline syncobj through execbuf";
+static void test_syncobj_timeline_signal(int fd)
+{
+ const uint32_t bbe = MI_BATCH_BUFFER_END;
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+ struct drm_i915_gem_exec_fence fence = {
+ .handle = syncobj_create(fd, 0),
+ };
+ uint64_t value = 42, query_value;
+ igt_spin_t *spin;
+
+ /* Check that the syncobj is signaled only when our request/fence is */
+
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 0;
+
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
+
+ fence.flags = I915_EXEC_FENCE_SIGNAL;
+
+ /* Check syncobj after waiting on the buffer handle. */
+ spin = igt_spin_new(fd);
+ gem_execbuf(fd, &execbuf);
+
+ igt_assert(gem_bo_busy(fd, obj.handle));
+ igt_assert(syncobj_busy(fd, fence.handle));
+ igt_assert(syncobj_timeline_wait(fd, &fence.handle, &value, 1, 0,
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE, NULL));
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &fence.handle, &value,
+ 1, 0, 0), -ETIME);
+
+ igt_spin_free(fd, spin);
+
+ gem_sync(fd, obj.handle);
+ igt_assert(!syncobj_busy(fd, fence.handle));
+ igt_assert(!gem_bo_busy(fd, obj.handle));
+
+ syncobj_timeline_query(fd, &fence.handle, &query_value, 1);
+ igt_assert_eq(query_value, value);
+
+ spin = igt_spin_new(fd);
+
+ /*
+ * Wait on the syncobj and verify the state of the buffer
+ * handle.
+ */
+ value = 84;
+ gem_execbuf(fd, &execbuf);
+
+ igt_assert(gem_bo_busy(fd, obj.handle));
+ igt_assert(gem_bo_busy(fd, obj.handle));
+ igt_assert(syncobj_busy(fd, fence.handle));
+ igt_assert(syncobj_timeline_wait(fd, &fence.handle, &value, 1, 0,
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE, NULL));
+ igt_assert_eq(syncobj_timeline_wait_err(fd, &fence.handle, &value,
+ 1, 0, 0), -ETIME);
+
+ igt_spin_free(fd, spin);
+
+ igt_assert(syncobj_timeline_wait(fd, &fence.handle, &value, 1,
+ gettime_ns() + NSEC_PER_SEC,
+ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT, NULL));
+
+ igt_assert(!gem_bo_busy(fd, obj.handle));
+ igt_assert(!syncobj_busy(fd, fence.handle));
+
+ syncobj_timeline_query(fd, &fence.handle, &query_value, 1);
+ igt_assert_eq(query_value, value);
+
+ gem_close(fd, obj.handle);
+ syncobj_destroy(fd, fence.handle);
+}
+
+static const char *test_syncobj_timeline_wait_desc =
+ "Verifies that waiting on a timeline syncobj point between engines"
+ " works";
+static void test_syncobj_timeline_wait(int fd)
+{
+ const uint32_t bbe[2] = {
+ MI_BATCH_BUFFER_END,
+ MI_NOOP,
+ };
+ uint32_t gem_context = gem_context_clone_with_engines(fd, 0);
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+ struct drm_i915_gem_exec_fence fence = {
+ .handle = syncobj_create(fd, 0),
+ };
+ uint64_t value = 1;
+ igt_spin_t *spin;
+ unsigned handle[16];
+ int n;
+
+ /* Check that we can use the syncobj to asynchronous wait prior to
+ * execution.
+ */
+
+ gem_quiescent_gpu(fd);
+
+ spin = igt_spin_new(fd);
+
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ execbuf.batch_len = sizeof(bbe);
+ execbuf.rsvd1 = gem_context;
+
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+ /* Queue a signaler from the blocked engine */
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 0;
+ fence.flags = I915_EXEC_FENCE_SIGNAL;
+ gem_execbuf(fd, &execbuf);
+ igt_assert(gem_bo_busy(fd, spin->handle));
+
+ gem_close(fd, obj.handle);
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+ n = 0;
+ for_each_engine(engine, fd) {
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+ /* No inter-engine synchronisation, will complete */
+ if (engine->flags == I915_EXEC_BLT) {
+ execbuf.flags = engine->flags;
+ execbuf.cliprects_ptr = 0;
+ execbuf.num_cliprects = 0;
+ gem_execbuf(fd, &execbuf);
+ gem_sync(fd, obj.handle);
+ igt_assert(gem_bo_busy(fd, spin->handle));
+ }
+ igt_assert(gem_bo_busy(fd, spin->handle));
+
+ /* Now wait upon the blocked engine */
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS | engine->flags;
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 0;
+ fence.flags = I915_EXEC_FENCE_WAIT;
+ gem_execbuf(fd, &execbuf);
+
+ igt_assert(gem_bo_busy(fd, obj.handle));
+ handle[n++] = obj.handle;
+ }
+ syncobj_destroy(fd, fence.handle);
+
+ for (int i = 0; i < n; i++)
+ igt_assert(gem_bo_busy(fd, handle[i]));
+
+ igt_spin_free(fd, spin);
+
+ for (int i = 0; i < n; i++) {
+ gem_sync(fd, handle[i]);
+ gem_close(fd, handle[i]);
+ }
+
+ gem_context_destroy(fd, gem_context);
+}
+
+static const char *test_syncobj_timeline_export_desc =
+ "Verify exporting of timeline syncobj signaled by i915";
+static void test_syncobj_timeline_export(int fd)
+{
+ const uint32_t bbe[2] = {
+ MI_BATCH_BUFFER_END,
+ MI_NOOP,
+ };
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+ struct drm_i915_gem_exec_fence fence = {
+ .handle = syncobj_create(fd, 0),
+ };
+ uint64_t value = 1;
+ int export[2];
+ igt_spin_t *spin = igt_spin_new(fd);
+
+ /* Check that if we export the syncobj prior to use it picks up
+ * the later fence. This allows a syncobj to establish a channel
+ * between clients that may be updated to a later fence by either
+ * end.
+ */
+ for (int n = 0; n < ARRAY_SIZE(export); n++)
+ export[n] = syncobj_export(fd, fence.handle);
+
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(&fence);
+ timeline_fences.values_ptr = to_user_pointer(&value);
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 0;
+
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+ fence.flags = I915_EXEC_FENCE_SIGNAL;
+ gem_execbuf(fd, &execbuf);
+
+ igt_assert(syncobj_busy(fd, fence.handle));
+ igt_assert(gem_bo_busy(fd, obj.handle));
+
+ for (int n = 0; n < ARRAY_SIZE(export); n++) {
+ uint32_t import = syncobj_import(fd, export[n]);
+ igt_assert(syncobj_busy(fd, import));
+ syncobj_destroy(fd, import);
+ }
+
+ igt_spin_free(fd, spin);
+
+ gem_sync(fd, obj.handle);
+ igt_assert(!gem_bo_busy(fd, obj.handle));
+ igt_assert(!syncobj_busy(fd, fence.handle));
+
+ gem_close(fd, obj.handle);
+ syncobj_destroy(fd, fence.handle);
+
+ for (int n = 0; n < ARRAY_SIZE(export); n++) {
+ uint32_t import = syncobj_import(fd, export[n]);
+ igt_assert(!syncobj_busy(fd, import));
+ syncobj_destroy(fd, import);
+ close(export[n]);
+ }
+}
+
+static const char *test_syncobj_timeline_repeat_desc =
+ "Verifies that waiting & signaling a same timeline syncobj point within"
+ " the same execbuf fworks";
+static void test_syncobj_timeline_repeat(int fd)
+{
+ const uint32_t bbe[2] = {
+ MI_BATCH_BUFFER_END,
+ MI_NOOP,
+ };
+ const unsigned nfences = 4096;
+ struct drm_i915_gem_exec_object2 obj;
+ struct drm_i915_gem_execbuffer2 execbuf;
+ struct drm_i915_gem_execbuffer_ext_timeline_fences timeline_fences;
+ struct drm_i915_gem_exec_fence *fence;
+ uint64_t *values;
+ int export;
+ igt_spin_t *spin = igt_spin_new(fd);
+
+ /* Check that we can wait on the same fence multiple times */
+ fence = calloc(nfences, sizeof(*fence));
+ values = calloc(nfences, sizeof(*values));
+ fence->handle = syncobj_create(fd, 0);
+ values[0] = 1;
+ export = syncobj_export(fd, fence->handle);
+ for (int i = 1; i < nfences; i++) {
+ fence[i].handle = syncobj_import(fd, export);
+ values[i] = i + 1;
+ }
+ close(export);
+
+ memset(&timeline_fences, 0, sizeof(timeline_fences));
+ timeline_fences.base.name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES;
+ timeline_fences.fence_count = 1;
+ timeline_fences.handles_ptr = to_user_pointer(fence);
+ timeline_fences.values_ptr = to_user_pointer(values);
+
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = to_user_pointer(&obj);
+ execbuf.buffer_count = 1;
+ execbuf.flags = I915_EXEC_USE_EXTENSIONS;
+ execbuf.cliprects_ptr = to_user_pointer(&timeline_fences);
+ execbuf.num_cliprects = 0;
+
+ memset(&obj, 0, sizeof(obj));
+ obj.handle = gem_create(fd, 4096);
+ gem_write(fd, obj.handle, 0, bbe, sizeof(bbe));
+
+ for (int i = 0; i < nfences; i++)
+ fence[i].flags = I915_EXEC_FENCE_SIGNAL;
+
+ gem_execbuf(fd, &execbuf);
+
+ for (int i = 0; i < nfences; i++) {
+ igt_assert(syncobj_busy(fd, fence[i].handle));
+ /*
+ * Timeline syncobj cannot resignal the same point
+ * again.
+ */
+ fence[i].flags |= I915_EXEC_FENCE_WAIT;
+ }
+ igt_assert(gem_bo_busy(fd, obj.handle));
+
+ igt_assert_eq(__gem_execbuf(fd, &execbuf), -EINVAL);
+
+ for (int i = 0; i < nfences; i++) {
+ igt_assert(syncobj_busy(fd, fence[i].handle));
+ fence[i].flags = I915_EXEC_FENCE_WAIT;
+ }
+ igt_assert(gem_bo_busy(fd, obj.handle));
+
+ gem_execbuf(fd, &execbuf);
+
+ for (int i = 0; i < nfences; i++)
+ igt_assert(syncobj_busy(fd, fence[i].handle));
+ igt_assert(gem_bo_busy(fd, obj.handle));
+
+ igt_spin_free(fd, spin);
+
+ gem_sync(fd, obj.handle);
+ gem_close(fd, obj.handle);
+
+ for (int i = 0; i < nfences; i++) {
+ igt_assert(!syncobj_busy(fd, fence[i].handle));
+ syncobj_destroy(fd, fence[i].handle);
+ }
+ free(fence);
+ free(values);
+}
+
igt_main
{
const struct intel_execution_engine2 *e;
@@ -1818,6 +2458,50 @@ igt_main
}
}
+ igt_subtest_group { /* syncobj timeline */
+ igt_fixture {
+ igt_require(exec_has_timeline_fences(i915));
+ igt_assert(has_syncobj_timeline(i915));
+ igt_fork_hang_detector(i915);
+ }
+
+ igt_describe(test_invalid_timeline_fence_array_desc);
+ igt_subtest("invalid-timeline-fence-array")
+ test_invalid_timeline_fence_array(i915);
+
+ igt_describe(test_syncobj_timeline_unused_fence_desc);
+ igt_subtest("syncobj-timeline-unused-fence")
+ test_syncobj_timeline_unused_fence(i915);
+
+ igt_describe(test_syncobj_timeline_invalid_wait_desc);
+ igt_subtest("syncobj-timeline-invalid-wait")
+ test_syncobj_timeline_invalid_wait(i915);
+
+ igt_describe(test_syncobj_timeline_invalid_flags_desc);
+ igt_subtest("syncobj-timeline-invalid-flags")
+ test_syncobj_timeline_invalid_flags(i915);
+
+ igt_describe(test_syncobj_timeline_signal_desc);
+ igt_subtest("syncobj-timeline-signal")
+ test_syncobj_timeline_signal(i915);
+
+ igt_describe(test_syncobj_timeline_wait_desc);
+ igt_subtest("syncobj-timeline-wait")
+ test_syncobj_timeline_wait(i915);
+
+ igt_describe(test_syncobj_timeline_export_desc);
+ igt_subtest("syncobj-timeline-export")
+ test_syncobj_timeline_export(i915);
+
+ igt_describe(test_syncobj_timeline_repeat_desc);
+ igt_subtest("syncobj-timeline-repeat")
+ test_syncobj_timeline_repeat(i915);
+
+ igt_fixture {
+ igt_stop_hang_detector();
+ }
+ }
+
igt_fixture {
close(i915);
}
--
2.28.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [igt-dev] [PATCH i-g-t 5/5] tests/i915/gem_exec_fence: add engine chaining tests
2020-07-31 13:41 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
` (3 preceding siblings ...)
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 4/5] tests/i915/exec_fence: add timeline fence tests Lionel Landwerlin
@ 2020-07-31 13:41 ` Lionel Landwerlin
2020-07-31 14:13 ` [igt-dev] ✓ Fi.CI.BAT: success for tests: Add timeline semaphore tests (rev2) Patchwork
2020-07-31 19:15 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
6 siblings, 0 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2020-07-31 13:41 UTC (permalink / raw)
To: igt-dev
Those tests are meant to verify the ordering while messing around with
the timeline points.
v2: Add munmap() (Chris)
v3: Rebase
Drop gem_context_set_all_engines()
Fix subtest require on number of engines
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
lib/intel_reg.h | 2 +
tests/i915/gem_exec_fence.c | 635 ++++++++++++++++++++++++++++++++++++
2 files changed, 637 insertions(+)
diff --git a/lib/intel_reg.h b/lib/intel_reg.h
index 0a9ee34c..ac1fc6cb 100644
--- a/lib/intel_reg.h
+++ b/lib/intel_reg.h
@@ -2596,6 +2596,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Batch */
#define MI_BATCH_BUFFER ((0x30 << 23) | 1)
#define MI_BATCH_BUFFER_START (0x31 << 23)
+#define MI_BATCH_BUFFER_START_GEN8 ((0x31 << 13) | 1)
+#define MI_BATCH_PREDICATE (1 << 15) /* HSW+ on RCS only*/
#define MI_BATCH_BUFFER_END (0xA << 23)
#define MI_COND_BATCH_BUFFER_END (0x36 << 23)
#define MI_DO_COMPARE (1 << 21)
diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 97439b4b..403fe081 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -2220,6 +2220,617 @@ static void test_syncobj_timeline_repeat(int fd)
free(values);
}
+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+
+/* #define MI_LOAD_REGISTER_MEM (MI_INSTR(0x29, 1) */
+/* #define MI_LOAD_REGISTER_MEM_GEN8 MI_INSTR(0x29, 2) */
+
+#define MI_LOAD_REGISTER_REG MI_INSTR(0x2A, 1)
+
+#define MI_STORE_REGISTER_MEM MI_INSTR(0x24, 1)
+#define MI_STORE_REGISTER_MEM_GEN8 MI_INSTR(0x24, 2)
+
+#define MI_MATH(x) MI_INSTR(0x1a, (x) - 1)
+#define MI_MATH_INSTR(opcode, op1, op2) ((opcode) << 20 | (op1) << 10 | (op2))
+/* Opcodes for MI_MATH_INSTR */
+#define MI_MATH_NOOP MI_MATH_INSTR(0x00, 0x0, 0x0)
+#define MI_MATH_LOAD(op1, op2) MI_MATH_INSTR(0x80, op1, op2)
+#define MI_MATH_LOADINV(op1, op2) MI_MATH_INSTR(0x480, op1, op2)
+#define MI_MATH_ADD MI_MATH_INSTR(0x100, 0x0, 0x0)
+#define MI_MATH_SUB MI_MATH_INSTR(0x101, 0x0, 0x0)
+#define MI_MATH_AND MI_MATH_INSTR(0x102, 0x0, 0x0)
+#define MI_MATH_OR MI_MATH_INSTR(0x103, 0x0, 0x0)
+#define MI_MATH_XOR MI_MATH_INSTR(0x104, 0x0, 0x0)
+#define MI_MATH_STORE(op1, op2) MI_MATH_INSTR(0x180, op1, op2)
+#define MI_MATH_STOREINV(op1, op2) MI_MATH_INSTR(0x580, op1, op2)
+/* Registers used as operands in MI_MATH_INSTR */
+#define MI_MATH_REG(x) (x)
+#define MI_MATH_REG_SRCA 0x20
+#define MI_MATH_REG_SRCB 0x21
+#define MI_MATH_REG_ACCU 0x31
+#define MI_MATH_REG_ZF 0x32
+#define MI_MATH_REG_CF 0x33
+
+#define HSW_CS_GPR(n) (0x600 + 8*(n))
+#define RING_TIMESTAMP (0x358)
+#define MI_PREDICATE_RESULT_1 (0x41c)
+
+struct inter_engine_context {
+ int fd;
+
+ struct {
+ uint32_t context;
+ } iterations[9];
+
+ struct intel_engine_data *engines;
+
+ struct inter_engine_batches {
+ void *increment_bb;
+ uint32_t increment_bb_len;
+ uint32_t increment_bb_handle;
+
+ uint32_t timeline;
+
+ void *read0_ptrs[2];
+ void *read1_ptrs[2];
+ void *write_ptrs[2];
+ } *batches;
+
+ void *wait_bb;
+ uint32_t wait_bb_len;
+ uint32_t wait_bb_handle;
+
+ void *jump_ptr;
+ void *timestamp2_ptr;
+
+ uint32_t wait_context;
+ uint32_t wait_timeline;
+
+ struct drm_i915_gem_exec_object2 engine_counter_object;
+};
+
+static void submit_timeline_execbuf(struct inter_engine_context *context,
+ struct drm_i915_gem_execbuffer2 *execbuf,
+ uint32_t run_engine_idx,
+ uint32_t wait_syncobj,
+ uint64_t wait_value,
+ uint32_t signal_syncobj,
+ uint64_t signal_value)
+{
+ uint64_t values[2] = { 0, };
+ struct drm_i915_gem_exec_fence fences[2] = { 0, };
+ struct drm_i915_gem_execbuffer_ext_timeline_fences fence_list = {
+ .base = {
+ .name = DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES,
+ },
+ .handles_ptr = to_user_pointer(fences),
+ .values_ptr = to_user_pointer(values),
+ };
+
+ if (wait_syncobj) {
+ fences[fence_list.fence_count] = (struct drm_i915_gem_exec_fence) {
+ .handle = wait_syncobj,
+ .flags = I915_EXEC_FENCE_WAIT,
+ };
+ values[fence_list.fence_count] = wait_value;
+ fence_list.fence_count++;
+ }
+
+ if (signal_syncobj) {
+ fences[fence_list.fence_count] = (struct drm_i915_gem_exec_fence) {
+ .handle = signal_syncobj,
+ .flags = I915_EXEC_FENCE_SIGNAL,
+ };
+ values[fence_list.fence_count] = signal_value;
+ fence_list.fence_count++;
+ }
+
+ if (wait_syncobj || signal_syncobj) {
+ execbuf->flags |= I915_EXEC_USE_EXTENSIONS;
+ execbuf->cliprects_ptr = to_user_pointer(&fence_list);
+ }
+
+ execbuf->flags |= context->engines->engines[run_engine_idx].flags;
+
+ gem_execbuf(context->fd, execbuf);
+}
+
+static void build_wait_bb(struct inter_engine_context *context,
+ uint64_t delay,
+ uint64_t timestamp_frequency)
+{
+ uint32_t *bb = context->wait_bb = calloc(1, 4096);
+ uint64_t wait_value =
+ 0xffffffffffffffff - (delay * timestamp_frequency) / NSEC_PER_SEC;
+
+ igt_debug("wait_value=0x%lx\n", wait_value);
+
+ *bb++ = MI_LOAD_REGISTER_IMM;
+ *bb++ = 0x2000 + HSW_CS_GPR(0);
+ *bb++ = wait_value & 0xffffffff;
+ *bb++ = MI_LOAD_REGISTER_IMM;
+ *bb++ = 0x2000 + HSW_CS_GPR(0) + 4;
+ *bb++ = wait_value >> 32;
+
+ *bb++ = MI_LOAD_REGISTER_REG;
+ *bb++ = 0x2000 + RING_TIMESTAMP;
+ *bb++ = 0x2000 + HSW_CS_GPR(1);
+ *bb++ = MI_LOAD_REGISTER_IMM;
+ *bb++ = 0x2000 + HSW_CS_GPR(1) + 4;
+ *bb++ = 0;
+
+ context->timestamp2_ptr = bb;
+ *bb++ = MI_LOAD_REGISTER_REG;
+ *bb++ = 0x2000 + RING_TIMESTAMP;
+ *bb++ = 0x2000 + HSW_CS_GPR(2);
+ *bb++ = MI_LOAD_REGISTER_IMM;
+ *bb++ = 0x2000 + HSW_CS_GPR(2) + 4;
+ *bb++ = 0;
+
+ *bb++ = MI_MATH(4);
+ *bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCA, MI_MATH_REG(2));
+ *bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCB, MI_MATH_REG(1));
+ *bb++ = MI_MATH_SUB;
+ *bb++ = MI_MATH_STORE(MI_MATH_REG(3), MI_MATH_REG_ACCU);
+
+ *bb++ = MI_MATH(4);
+ *bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCA, MI_MATH_REG(0));
+ *bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCB, MI_MATH_REG(3));
+ *bb++ = MI_MATH_ADD;
+ *bb++ = MI_MATH_STOREINV(MI_MATH_REG(4), MI_MATH_REG_CF);
+
+ *bb++ = MI_LOAD_REGISTER_REG;
+ *bb++ = 0x2000 + HSW_CS_GPR(4);
+ *bb++ = 0x2000 + MI_PREDICATE_RESULT_1;
+
+ *bb++ = MI_BATCH_BUFFER_START | MI_BATCH_PREDICATE | 1;
+ context->jump_ptr = bb;
+ *bb++ = 0;
+ *bb++ = 0;
+
+ *bb++ = MI_BATCH_BUFFER_END;
+
+ context->wait_bb_len = ALIGN((void *) bb - context->wait_bb, 8);
+}
+
+static void wait_engine(struct inter_engine_context *context,
+ uint32_t run_engine_idx,
+ uint32_t signal_syncobj,
+ uint64_t signal_value)
+{
+ struct drm_i915_gem_relocation_entry relocs[1];
+ struct drm_i915_gem_exec_object2 objects[2] = {
+ context->engine_counter_object,
+ {
+ .handle = context->wait_bb_handle,
+ .relocs_ptr = to_user_pointer(&relocs),
+ .relocation_count = ARRAY_SIZE(relocs),
+ },
+ };
+ struct drm_i915_gem_execbuffer2 execbuf = {
+ .buffers_ptr = to_user_pointer(&objects[0]),
+ .buffer_count = 2,
+ .flags = I915_EXEC_HANDLE_LUT,
+ .rsvd1 = context->wait_context,
+ .batch_len = context->wait_bb_len,
+ };
+
+ memset(&relocs, 0, sizeof(relocs));
+
+ /* MI_BATCH_BUFFER_START */
+ relocs[0].target_handle = 1;
+ relocs[0].delta = context->timestamp2_ptr - context->wait_bb;
+ relocs[0].offset = context->jump_ptr - context->wait_bb;
+ relocs[0].presumed_offset = -1;
+
+ submit_timeline_execbuf(context, &execbuf, run_engine_idx,
+ 0, 0,
+ signal_syncobj, signal_value);
+}
+
+static void build_increment_engine_bb(struct inter_engine_batches *batch,
+ uint32_t mmio_base)
+{
+ uint32_t *bb = batch->increment_bb = calloc(1, 4096);
+
+ *bb++ = MI_LOAD_REGISTER_MEM_GEN8;
+ *bb++ = mmio_base + HSW_CS_GPR(0);
+ batch->read0_ptrs[0] = bb;
+ *bb++ = 0;
+ *bb++ = 0;
+ *bb++ = MI_LOAD_REGISTER_MEM_GEN8;
+ *bb++ = mmio_base + HSW_CS_GPR(0) + 4;
+ batch->read0_ptrs[1] = bb;
+ *bb++ = 0;
+ *bb++ = 0;
+
+ *bb++ = MI_LOAD_REGISTER_MEM_GEN8;
+ *bb++ = mmio_base + HSW_CS_GPR(1);
+ batch->read1_ptrs[0] = bb;
+ *bb++ = 0;
+ *bb++ = 0;
+ *bb++ = MI_LOAD_REGISTER_MEM_GEN8;
+ *bb++ = mmio_base + HSW_CS_GPR(1) + 4;
+ batch->read1_ptrs[1] = bb;
+ *bb++ = 0;
+ *bb++ = 0;
+
+ *bb++ = MI_MATH(4);
+ *bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCA, MI_MATH_REG(0));
+ *bb++ = MI_MATH_LOAD(MI_MATH_REG_SRCB, MI_MATH_REG(1));
+ *bb++ = MI_MATH_ADD;
+ *bb++ = MI_MATH_STORE(MI_MATH_REG(0), MI_MATH_REG_ACCU);
+
+ *bb++ = MI_STORE_REGISTER_MEM_GEN8;
+ *bb++ = mmio_base + HSW_CS_GPR(0);
+ batch->write_ptrs[0] = bb;
+ *bb++ = 0;
+ *bb++ = 0;
+ *bb++ = MI_STORE_REGISTER_MEM_GEN8;
+ *bb++ = mmio_base + HSW_CS_GPR(0) + 4;
+ batch->write_ptrs[1] = bb;
+ *bb++ = 0;
+ *bb++ = 0;
+
+ *bb++ = MI_BATCH_BUFFER_END;
+
+ batch->increment_bb_len = ALIGN((void *) bb - batch->increment_bb, 8);
+}
+
+static void increment_engine(struct inter_engine_context *context,
+ uint32_t gem_context,
+ uint32_t read0_engine_idx,
+ uint32_t read1_engine_idx,
+ uint32_t write_engine_idx,
+ uint32_t wait_syncobj,
+ uint64_t wait_value,
+ uint32_t signal_syncobj,
+ uint64_t signal_value)
+{
+ struct inter_engine_batches *batch = &context->batches[write_engine_idx];
+ struct drm_i915_gem_relocation_entry relocs[3 * 2];
+ struct drm_i915_gem_exec_object2 objects[2] = {
+ context->engine_counter_object,
+ {
+ .handle = batch->increment_bb_handle,
+ .relocs_ptr = to_user_pointer(relocs),
+ .relocation_count = ARRAY_SIZE(relocs),
+ },
+ };
+ struct drm_i915_gem_execbuffer2 execbuf = {
+ .buffers_ptr = to_user_pointer(&objects[0]),
+ .buffer_count = ARRAY_SIZE(objects),
+ .flags = I915_EXEC_HANDLE_LUT,
+ .rsvd1 = gem_context,
+ .batch_len = batch->increment_bb_len,
+ };
+
+ memset(relocs, 0, sizeof(relocs));
+
+ /* MI_LOAD_REGISTER_MEM */
+ relocs[0].target_handle = 0;
+ relocs[0].delta = read0_engine_idx * 8;
+ relocs[0].offset = batch->read0_ptrs[0] - batch->increment_bb;
+ relocs[0].presumed_offset = -1;
+ relocs[1].target_handle = 0;
+ relocs[1].delta = read0_engine_idx * 8 + 4;
+ relocs[1].offset = batch->read0_ptrs[1] - batch->increment_bb;
+ relocs[1].presumed_offset = -1;
+
+ /* MI_LOAD_REGISTER_MEM */
+ relocs[2].target_handle = 0;
+ relocs[2].delta = read1_engine_idx * 8;
+ relocs[2].offset = batch->read1_ptrs[0] - batch->increment_bb;
+ relocs[2].presumed_offset = -1;
+ relocs[3].target_handle = 0;
+ relocs[3].delta = read1_engine_idx * 8 + 4;
+ relocs[3].offset = batch->read1_ptrs[1] - batch->increment_bb;
+ relocs[3].presumed_offset = -1;
+
+ /* MI_STORE_REGISTER_MEM */
+ relocs[4].target_handle = 0;
+ relocs[4].delta = write_engine_idx * 8;
+ relocs[4].offset = batch->write_ptrs[0] - batch->increment_bb;
+ relocs[4].presumed_offset = -1;
+ relocs[5].target_handle = 0;
+ relocs[5].delta = write_engine_idx * 8 + 4;
+ relocs[5].offset = batch->write_ptrs[1] - batch->increment_bb;
+ relocs[5].presumed_offset = -1;
+
+ submit_timeline_execbuf(context, &execbuf, write_engine_idx,
+ wait_syncobj, wait_value,
+ signal_syncobj, signal_value);
+
+ context->engine_counter_object = objects[0];
+}
+
+static uint64_t fib(uint32_t iters)
+{
+ uint64_t last_value = 0;
+ uint64_t value = 1;
+ uint32_t i = 0;
+
+ while (i < iters) {
+ uint64_t new_value = value + last_value;
+
+ last_value = value;
+ value = new_value;
+ i++;
+ }
+
+ return last_value;
+}
+
+static uint64_t
+get_cs_timestamp_frequency(int fd)
+{
+ int cs_ts_freq = 0;
+ drm_i915_getparam_t gp;
+
+ gp.param = I915_PARAM_CS_TIMESTAMP_FREQUENCY;
+ gp.value = &cs_ts_freq;
+ if (igt_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0)
+ return cs_ts_freq;
+
+ igt_skip("Kernel with PARAM_CS_TIMESTAMP_FREQUENCY support required\n");
+}
+
+static void setup_timeline_chain_engines(struct inter_engine_context *context, int fd, struct intel_engine_data *engines)
+{
+ memset(context, 0, sizeof(*context));
+
+ context->fd = fd;
+ context->engines = engines;
+
+ context->wait_context = gem_context_create(fd);
+ context->wait_timeline = syncobj_create(fd, 0);
+
+ context->engine_counter_object.handle = gem_create(fd, 4096);
+
+ for (uint32_t i = 0; i < ARRAY_SIZE(context->iterations); i++) {
+ context->iterations[i].context = gem_context_clone_with_engines(fd, 0);
+
+ /* Give a different priority to all contexts. */
+ gem_context_set_priority(fd, context->iterations[i].context,
+ I915_CONTEXT_MAX_USER_PRIORITY - ARRAY_SIZE(context->iterations) + i);
+ }
+
+ build_wait_bb(context, 20 * 1000 * 1000ull /* 20ms */, get_cs_timestamp_frequency(fd));
+ context->wait_bb_handle = gem_create(fd, 4096);
+ gem_write(fd, context->wait_bb_handle, 0,
+ context->wait_bb, context->wait_bb_len);
+
+ context->batches = calloc(engines->nengines, sizeof(*context->batches));
+ for (uint32_t e = 0; e < engines->nengines; e++) {
+ struct inter_engine_batches *batches = &context->batches[e];
+
+ batches->timeline = syncobj_create(fd, 0);
+
+ build_increment_engine_bb(
+ batches,
+ gem_engine_mmio_base(fd, engines->engines[e].name));
+ batches->increment_bb_handle = gem_create(fd, 4096);
+ gem_write(fd, batches->increment_bb_handle, 0,
+ batches->increment_bb, batches->increment_bb_len);
+ }
+
+ for (uint32_t i = 0; i < 10; i++)
+ igt_debug("%u = %lu\n", i, fib(i));
+
+ /* Bootstrap the fibonacci sequence */
+ {
+ uint64_t dword = 1;
+ gem_write(fd, context->engine_counter_object.handle,
+ sizeof(dword) * (context->engines->nengines - 1),
+ &dword, sizeof(dword));
+ }
+}
+
+static void teardown_timeline_chain_engines(struct inter_engine_context *context)
+{
+ gem_close(context->fd, context->engine_counter_object.handle);
+
+ for (uint32_t i = 0; i < ARRAY_SIZE(context->iterations); i++) {
+ gem_context_destroy(context->fd, context->iterations[i].context);
+ }
+
+ gem_context_destroy(context->fd, context->wait_context);
+ syncobj_destroy(context->fd, context->wait_timeline);
+ gem_close(context->fd, context->wait_bb_handle);
+ free(context->wait_bb);
+
+ for (uint32_t e = 0; e < context->engines->nengines; e++) {
+ struct inter_engine_batches *batches = &context->batches[e];
+
+ syncobj_destroy(context->fd, batches->timeline);
+ gem_close(context->fd, batches->increment_bb_handle);
+ free(batches->increment_bb);
+ }
+ free(context->batches);
+}
+
+static void test_syncobj_timeline_chain_engines(int fd, struct intel_engine_data *engines)
+{
+ struct inter_engine_context ctx;
+ uint64_t *counter_output;
+
+ setup_timeline_chain_engines(&ctx, fd, engines);
+
+ /*
+ * Delay all the other operations by making them depend on an
+ * active wait on the RCS.
+ */
+ wait_engine(&ctx, 0, ctx.wait_timeline, 1);
+
+ for (uint32_t iter = 0; iter < ARRAY_SIZE(ctx.iterations); iter++) {
+ for (uint32_t engine = 0; engine < engines->nengines; engine++) {
+ uint32_t prev_prev_engine =
+ (engines->nengines + engine - 2) % engines->nengines;
+ uint32_t prev_engine =
+ (engines->nengines + engine - 1) % engines->nengines;
+ /*
+ * Pick up the wait engine semaphore for the
+ * first increment, then pick up the previous
+ * engine's timeline.
+ */
+ uint32_t wait_syncobj =
+ iter == 0 && engine == 0 ?
+ ctx.wait_timeline : ctx.batches[prev_engine].timeline;
+ uint32_t wait_value =
+ iter == 0 && engine == 0 ?
+ 1 : (engine == 0 ? iter : (iter + 1));
+
+ increment_engine(&ctx, ctx.iterations[iter].context,
+ prev_prev_engine /* read0 engine */,
+ prev_engine /* read1 engine */,
+ engine /* write engine */,
+ wait_syncobj, wait_value,
+ ctx.batches[engine].timeline, iter + 1);
+ }
+ }
+
+ gem_sync(fd, ctx.engine_counter_object.handle);
+
+ counter_output = gem_mmap__wc(fd, ctx.engine_counter_object.handle, 0, 4096, PROT_READ);
+
+ for (uint32_t i = 0; i < ctx.engines->nengines; i++)
+ igt_debug("engine %i (%s)\t= %016lx\n", i,
+ ctx.engines->engines[i].name, counter_output[i]);
+
+ /*
+ * Verify that we get the fibonacci number expected (we start
+ * at the sequence on the second number : 1).
+ */
+ igt_assert_eq(counter_output[engines->nengines - 1],
+ fib(ARRAY_SIZE(ctx.iterations) * engines->nengines + 1));
+
+ munmap(counter_output, 4096);
+
+ teardown_timeline_chain_engines(&ctx);
+}
+
+static void test_syncobj_stationary_timeline_chain_engines(int fd, struct intel_engine_data *engines)
+{
+ struct inter_engine_context ctx;
+ uint64_t *counter_output;
+
+ setup_timeline_chain_engines(&ctx, fd, engines);
+
+ /*
+ * Delay all the other operations by making them depend on an
+ * active wait on the RCS.
+ */
+ wait_engine(&ctx, 0, ctx.wait_timeline, 1);
+
+ for (uint32_t iter = 0; iter < ARRAY_SIZE(ctx.iterations); iter++) {
+ for (uint32_t engine = 0; engine < engines->nengines; engine++) {
+ uint32_t prev_prev_engine =
+ (engines->nengines + engine - 2) % engines->nengines;
+ uint32_t prev_engine =
+ (engines->nengines + engine - 1) % engines->nengines;
+ /*
+ * Pick up the wait engine semaphore for the
+ * first increment, then pick up the previous
+ * engine's timeline.
+ */
+ uint32_t wait_syncobj =
+ iter == 0 && engine == 0 ?
+ ctx.wait_timeline : ctx.batches[prev_engine].timeline;
+ /*
+ * Always signal the value 10. Because the
+ * signal operations are submitted in order,
+ * we should always pickup the right
+ * dma-fence.
+ */
+ uint32_t wait_value =
+ iter == 0 && engine == 0 ?
+ 1 : 10;
+
+ increment_engine(&ctx, ctx.iterations[iter].context,
+ prev_prev_engine /* read0 engine */,
+ prev_engine /* read1 engine */,
+ engine /* write engine */,
+ wait_syncobj, wait_value,
+ ctx.batches[engine].timeline, 10);
+ }
+ }
+
+ gem_sync(fd, ctx.engine_counter_object.handle);
+
+ counter_output = gem_mmap__wc(fd, ctx.engine_counter_object.handle, 0, 4096, PROT_READ);
+
+ for (uint32_t i = 0; i < ctx.engines->nengines; i++)
+ igt_debug("engine %i (%s)\t= %016lx\n", i,
+ ctx.engines->engines[i].name, counter_output[i]);
+ igt_assert_eq(counter_output[engines->nengines - 1],
+ fib(ARRAY_SIZE(ctx.iterations) * engines->nengines + 1));
+
+ munmap(counter_output, 4096);
+
+ teardown_timeline_chain_engines(&ctx);
+}
+
+static void test_syncobj_backward_timeline_chain_engines(int fd, struct intel_engine_data *engines)
+{
+ struct inter_engine_context ctx;
+ uint64_t *counter_output;
+
+ setup_timeline_chain_engines(&ctx, fd, engines);
+
+ /*
+ * Delay all the other operations by making them depend on an
+ * active wait on the RCS.
+ */
+ wait_engine(&ctx, 0, ctx.wait_timeline, 1);
+
+ for (uint32_t iter = 0; iter < ARRAY_SIZE(ctx.iterations); iter++) {
+ for (uint32_t engine = 0; engine < engines->nengines; engine++) {
+ uint32_t prev_prev_engine =
+ (engines->nengines + engine - 2) % engines->nengines;
+ uint32_t prev_engine =
+ (engines->nengines + engine - 1) % engines->nengines;
+ /*
+ * Pick up the wait engine semaphore for the
+ * first increment, then pick up the previous
+ * engine's timeline.
+ */
+ uint32_t wait_syncobj =
+ iter == 0 && engine == 0 ?
+ ctx.wait_timeline : ctx.batches[prev_engine].timeline;
+ /*
+ * Always signal the value 10. Because the
+ * signal operations are submitted in order,
+ * we should always pickup the right
+ * dma-fence.
+ */
+ uint32_t wait_value =
+ iter == 0 && engine == 0 ?
+ 1 : 1;
+
+ increment_engine(&ctx, ctx.iterations[iter].context,
+ prev_prev_engine /* read0 engine */,
+ prev_engine /* read1 engine */,
+ engine /* write engine */,
+ wait_syncobj, wait_value,
+ ctx.batches[engine].timeline, ARRAY_SIZE(ctx.iterations) - iter);
+ }
+ }
+
+ gem_sync(fd, ctx.engine_counter_object.handle);
+
+ counter_output = gem_mmap__wc(fd, ctx.engine_counter_object.handle, 0, 4096, PROT_READ);
+
+ for (uint32_t i = 0; i < ctx.engines->nengines; i++)
+ igt_debug("engine %i (%s)\t= %016lx\n", i,
+ ctx.engines->engines[i].name, counter_output[i]);
+ igt_assert_eq(counter_output[engines->nengines - 1],
+ fib(ARRAY_SIZE(ctx.iterations) * engines->nengines + 1));
+
+ munmap(counter_output, 4096);
+
+ teardown_timeline_chain_engines(&ctx);
+}
+
igt_main
{
const struct intel_execution_engine2 *e;
@@ -2497,6 +3108,30 @@ igt_main
igt_subtest("syncobj-timeline-repeat")
test_syncobj_timeline_repeat(i915);
+ igt_subtest_group { /* syncobj timeline engine chaining */
+ struct intel_engine_data engines;
+
+ igt_fixture {
+ /*
+ * We need support for MI_ALU on all
+ * engines which seems to be there
+ * only on Gen8+
+ */
+ igt_require(intel_gen(intel_get_drm_devid(i915)) >= 8);
+ engines = intel_init_engine_list(i915, 0);
+ igt_require(engines.nengines > 1);
+ }
+
+ igt_subtest("syncobj-timeline-chain-engines")
+ test_syncobj_timeline_chain_engines(i915, &engines);
+
+ igt_subtest("syncobj-stationary-timeline-chain-engines")
+ test_syncobj_stationary_timeline_chain_engines(i915, &engines);
+
+ igt_subtest("syncobj-backward-timeline-chain-engines")
+ test_syncobj_backward_timeline_chain_engines(i915, &engines);
+ }
+
igt_fixture {
igt_stop_hang_detector();
}
--
2.28.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [igt-dev] ✓ Fi.CI.BAT: success for tests: Add timeline semaphore tests (rev2)
2020-07-31 13:41 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
` (4 preceding siblings ...)
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 5/5] tests/i915/gem_exec_fence: add engine chaining tests Lionel Landwerlin
@ 2020-07-31 14:13 ` Patchwork
2020-07-31 19:15 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
6 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2020-07-31 14:13 UTC (permalink / raw)
To: Lionel Landwerlin; +Cc: igt-dev
[-- Attachment #1.1: Type: text/plain, Size: 5867 bytes --]
== Series Details ==
Series: tests: Add timeline semaphore tests (rev2)
URL : https://patchwork.freedesktop.org/series/79248/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_8822 -> IGTPW_4837
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/index.html
Known issues
------------
Here are the changes found in IGTPW_4837 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@i915_module_load@reload:
- fi-tgl-u2: [PASS][1] -> [DMESG-WARN][2] ([i915#1982])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-tgl-u2/igt@i915_module_load@reload.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-tgl-u2/igt@i915_module_load@reload.html
- fi-icl-y: [PASS][3] -> [DMESG-WARN][4] ([i915#1982])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-icl-y/igt@i915_module_load@reload.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-icl-y/igt@i915_module_load@reload.html
* igt@i915_pm_rpm@module-reload:
- fi-bsw-kefka: [PASS][5] -> [DMESG-WARN][6] ([i915#1982])
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-bsw-kefka/igt@i915_pm_rpm@module-reload.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-bsw-kefka/igt@i915_pm_rpm@module-reload.html
* igt@kms_chamelium@dp-crc-fast:
- fi-icl-u2: [PASS][7] -> [FAIL][8] ([i915#262])
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-icl-u2/igt@kms_chamelium@dp-crc-fast.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-icl-u2/igt@kms_chamelium@dp-crc-fast.html
* igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1:
- fi-icl-u2: [PASS][9] -> [DMESG-WARN][10] ([i915#1982])
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html
#### Possible fixes ####
* igt@i915_module_load@reload:
- fi-bsw-kefka: [DMESG-WARN][11] ([i915#1982]) -> [PASS][12]
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-bsw-kefka/igt@i915_module_load@reload.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-bsw-kefka/igt@i915_module_load@reload.html
* igt@i915_pm_rpm@basic-pci-d3-state:
- fi-byt-j1900: [DMESG-WARN][13] ([i915#1982]) -> [PASS][14]
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-byt-j1900/igt@i915_pm_rpm@basic-pci-d3-state.html
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-byt-j1900/igt@i915_pm_rpm@basic-pci-d3-state.html
* igt@kms_busy@basic@flip:
- {fi-tgl-dsi}: [DMESG-WARN][15] ([i915#1982]) -> [PASS][16]
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-tgl-dsi/igt@kms_busy@basic@flip.html
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-tgl-dsi/igt@kms_busy@basic@flip.html
- fi-kbl-x1275: [DMESG-WARN][17] ([i915#62] / [i915#92] / [i915#95]) -> [PASS][18]
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-kbl-x1275/igt@kms_busy@basic@flip.html
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-kbl-x1275/igt@kms_busy@basic@flip.html
* igt@kms_cursor_legacy@basic-flip-after-cursor-atomic:
- fi-icl-u2: [DMESG-WARN][19] ([i915#1982]) -> [PASS][20] +1 similar issue
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html
#### Warnings ####
* igt@gem_exec_suspend@basic-s0:
- fi-kbl-x1275: [DMESG-WARN][21] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][22] ([i915#62] / [i915#92]) +1 similar issue
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-kbl-x1275/igt@gem_exec_suspend@basic-s0.html
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-kbl-x1275/igt@gem_exec_suspend@basic-s0.html
* igt@kms_force_connector_basic@force-edid:
- fi-kbl-x1275: [DMESG-WARN][23] ([i915#62] / [i915#92]) -> [DMESG-WARN][24] ([i915#62] / [i915#92] / [i915#95]) +6 similar issues
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/fi-kbl-x1275/igt@kms_force_connector_basic@force-edid.html
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/fi-kbl-x1275/igt@kms_force_connector_basic@force-edid.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
[i915#262]: https://gitlab.freedesktop.org/drm/intel/issues/262
[i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
[i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
[i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95
Participating hosts (42 -> 36)
------------------------------
Missing (6): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper fi-bdw-samus
Build changes
-------------
* CI: CI-20190529 -> None
* IGT: IGT_5755 -> IGTPW_4837
CI-20190529: 20190529
CI_DRM_8822: 26bcf5c3ceadd2c69181a320c4363f58ae34be46 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_4837: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/index.html
IGT_5755: e9ef5db4cd286fb4bf151a24efcd7a62a4df18f1 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
== Testlist changes ==
+++ 132 lines
--- 0 lines
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/index.html
[-- Attachment #1.2: Type: text/html, Size: 7888 bytes --]
[-- Attachment #2: Type: text/plain, Size: 154 bytes --]
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 13+ messages in thread
* [igt-dev] ✓ Fi.CI.IGT: success for tests: Add timeline semaphore tests (rev2)
2020-07-31 13:41 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
` (5 preceding siblings ...)
2020-07-31 14:13 ` [igt-dev] ✓ Fi.CI.BAT: success for tests: Add timeline semaphore tests (rev2) Patchwork
@ 2020-07-31 19:15 ` Patchwork
6 siblings, 0 replies; 13+ messages in thread
From: Patchwork @ 2020-07-31 19:15 UTC (permalink / raw)
To: Lionel Landwerlin; +Cc: igt-dev
[-- Attachment #1.1: Type: text/plain, Size: 30260 bytes --]
== Series Details ==
Series: tests: Add timeline semaphore tests (rev2)
URL : https://patchwork.freedesktop.org/series/79248/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_8822_full -> IGTPW_4837_full
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/index.html
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in IGTPW_4837_full:
### IGT changes ###
#### Possible regressions ####
* {igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-submitted-signaled} (NEW):
- shard-iclb: NOTRUN -> [SKIP][1] +130 similar issues
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb6/igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-submitted-signaled.html
* {igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted-submitted-signaled} (NEW):
- shard-tglb: NOTRUN -> [SKIP][2] +130 similar issues
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-tglb8/igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted-submitted-signaled.html
New tests
---------
New tests have been introduced between CI_DRM_8822_full and IGTPW_4837_full:
### New IGT tests (132) ###
* igt@gem_exec_fence@invalid-timeline-fence-array:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-backward-timeline-chain-engines:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-stationary-timeline-chain-engines:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-timeline-chain-engines:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-timeline-export:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-timeline-invalid-flags:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-timeline-invalid-wait:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-timeline-repeat:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-timeline-signal:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-timeline-unused-fence:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@gem_exec_fence@syncobj-timeline-wait:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@32bits-limit:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@device-signal-unordered:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@device-submit-unordered:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-for-submit-available-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-for-submit-available-unsubmitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-for-submit-available-unsubmitted-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-for-submit-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-for-submit-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-for-submit-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-for-submit-unsubmitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-for-submit-unsubmitted-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-for-submit-unsubmitted-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-all-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-for-submit-available-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-for-submit-submitted:
- Statuses : 6 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-for-submit-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-for-submit-unsubmitted-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-multi-wait-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-single-wait-all-for-submit-available-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-single-wait-all-for-submit-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-single-wait-all-for-submit-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-single-wait-all-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-single-wait-for-submit-available-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-single-wait-for-submit-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-single-wait-for-submit-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@etime-single-wait-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@host-signal-ordered:
- Statuses : 6 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@host-signal-points:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-all-available-unsubmitted:
- Statuses : 1 timeout(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-all-available-unsubmitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-all-available-unsubmitted-submitted:
- Statuses : 6 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-all-available-unsubmitted-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-all-unsubmitted-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-available-unsubmitted-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-unsubmitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-unsubmitted-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-multi-wait-unsubmitted-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-query-bad-pad:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-query-illegal-handle:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-query-one-illegal-handle:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-query-zero-handles:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-signal-bad-pad:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-signal-illegal-handle:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-signal-illegal-point:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-signal-one-illegal-handle:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-signal-zero-handles:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-single-wait-all-available-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-single-wait-all-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-single-wait-available-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-single-wait-unsubmitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-transfer-bad-pad:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-transfer-illegal-handle:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-transfer-non-existent-point:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-wait-bad-flags:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-wait-illegal-handle:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@invalid-wait-zero-handles:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-all-available-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-all-available-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-all-available-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-all-for-submit-available-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-all-for-submit-available-submitted:
- Statuses : 6 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-all-for-submit-available-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-all-for-submit-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-all-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-available-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-available-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-available-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-available-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-available-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-available-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-available-unsubmitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-available-unsubmitted-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-available-unsubmitted-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-unsubmitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-for-submit-unsubmitted-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@multi-wait-submitted-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@reset-during-wait-for-submit:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@reset-multiple-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@reset-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@reset-unsignaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@signal:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@signal-array:
- Statuses : 6 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@signal-point-0:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-all-available-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-all-available-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-all-for-submit-available-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-all-for-submit-available-submitted:
- Statuses : 6 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-all-for-submit-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-all-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-available-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-available-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-for-submit-available-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-for-submit-available-submitted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-for-submit-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@single-wait-signaled:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@transfer-timeline-point:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-all-complex:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-all-delayed-signal:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-all-for-submit-complex:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-all-for-submit-delayed-submit:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-all-for-submit-snapshot:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-all-interrupted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-all-snapshot:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-any-complex:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-any-interrupted:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-any-snapshot:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-delayed-signal:
- Statuses : 6 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-for-submit-complex:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-for-submit-delayed-submit:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
* igt@syncobj_timeline@wait-for-submit-snapshot:
- Statuses : 7 skip(s)
- Exec time: [0.0] s
Known issues
------------
Here are the changes found in IGTPW_4837_full that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@dumb_buffer@map-invalid-size:
- shard-snb: [PASS][3] -> [TIMEOUT][4] ([i915#1958] / [i915#2119])
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-snb5/igt@dumb_buffer@map-invalid-size.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-snb5/igt@dumb_buffer@map-invalid-size.html
- shard-hsw: [PASS][5] -> [TIMEOUT][6] ([i915#1958] / [i915#2119])
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-hsw4/igt@dumb_buffer@map-invalid-size.html
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-hsw7/igt@dumb_buffer@map-invalid-size.html
* igt@gem_exec_create@forked:
- shard-glk: [PASS][7] -> [DMESG-WARN][8] ([i915#118] / [i915#95]) +2 similar issues
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-glk2/igt@gem_exec_create@forked.html
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-glk2/igt@gem_exec_create@forked.html
* igt@gem_exec_endless@dispatch@rcs0:
- shard-apl: [PASS][9] -> [INCOMPLETE][10] ([i915#1635] / [i915#2119])
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-apl3/igt@gem_exec_endless@dispatch@rcs0.html
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-apl4/igt@gem_exec_endless@dispatch@rcs0.html
* igt@gem_exec_reloc@basic-concurrent0:
- shard-glk: [PASS][11] -> [FAIL][12] ([i915#1930])
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-glk1/igt@gem_exec_reloc@basic-concurrent0.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-glk5/igt@gem_exec_reloc@basic-concurrent0.html
* igt@i915_module_load@reload:
- shard-iclb: [PASS][13] -> [DMESG-WARN][14] ([i915#1982])
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-iclb4/igt@i915_module_load@reload.html
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb6/igt@i915_module_load@reload.html
* igt@i915_pm_dc@dc3co-vpb-simulation:
- shard-tglb: [PASS][15] -> [SKIP][16] ([i915#1904])
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-tglb1/igt@i915_pm_dc@dc3co-vpb-simulation.html
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-tglb5/igt@i915_pm_dc@dc3co-vpb-simulation.html
* igt@i915_pm_rps@reset:
- shard-apl: [PASS][17] -> [FAIL][18] ([i915#1635]) +1 similar issue
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-apl3/igt@i915_pm_rps@reset.html
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-apl4/igt@i915_pm_rps@reset.html
* igt@kms_big_fb@y-tiled-64bpp-rotate-180:
- shard-glk: [PASS][19] -> [DMESG-FAIL][20] ([i915#118] / [i915#95])
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-glk2/igt@kms_big_fb@y-tiled-64bpp-rotate-180.html
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-glk8/igt@kms_big_fb@y-tiled-64bpp-rotate-180.html
* igt@kms_cursor_legacy@basic-flip-after-cursor-atomic:
- shard-tglb: [PASS][21] -> [DMESG-WARN][22] ([i915#1982]) +1 similar issue
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-tglb6/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-tglb6/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html
* igt@kms_flip@2x-flip-vs-dpms@ab-hdmi-a1-hdmi-a2:
- shard-glk: [PASS][23] -> [DMESG-WARN][24] ([i915#1982])
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-glk6/igt@kms_flip@2x-flip-vs-dpms@ab-hdmi-a1-hdmi-a2.html
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-glk3/igt@kms_flip@2x-flip-vs-dpms@ab-hdmi-a1-hdmi-a2.html
* igt@kms_flip@flip-vs-expired-vblank@c-hdmi-a2:
- shard-glk: [PASS][25] -> [FAIL][26] ([i915#79])
[25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-glk5/igt@kms_flip@flip-vs-expired-vblank@c-hdmi-a2.html
[26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-glk1/igt@kms_flip@flip-vs-expired-vblank@c-hdmi-a2.html
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt:
- shard-kbl: [PASS][27] -> [DMESG-WARN][28] ([i915#1982])
[27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-kbl4/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html
[28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-kbl7/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html
* igt@kms_hdr@bpc-switch-suspend:
- shard-kbl: [PASS][29] -> [DMESG-WARN][30] ([i915#180]) +7 similar issues
[29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-kbl4/igt@kms_hdr@bpc-switch-suspend.html
[30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-kbl4/igt@kms_hdr@bpc-switch-suspend.html
* igt@kms_panel_fitting@atomic-fastset:
- shard-tglb: [PASS][31] -> [FAIL][32] ([i915#83])
[31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-tglb2/igt@kms_panel_fitting@atomic-fastset.html
[32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-tglb5/igt@kms_panel_fitting@atomic-fastset.html
- shard-iclb: [PASS][33] -> [FAIL][34] ([i915#83])
[33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-iclb2/igt@kms_panel_fitting@atomic-fastset.html
[34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb2/igt@kms_panel_fitting@atomic-fastset.html
* igt@kms_psr@no_drrs:
- shard-iclb: [PASS][35] -> [FAIL][36] ([i915#173])
[35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-iclb3/igt@kms_psr@no_drrs.html
[36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb1/igt@kms_psr@no_drrs.html
* igt@kms_psr@psr2_basic:
- shard-iclb: [PASS][37] -> [SKIP][38] ([fdo#109441]) +1 similar issue
[37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-iclb2/igt@kms_psr@psr2_basic.html
[38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb4/igt@kms_psr@psr2_basic.html
* igt@kms_setmode@basic:
- shard-kbl: [PASS][39] -> [FAIL][40] ([i915#31])
[39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-kbl4/igt@kms_setmode@basic.html
[40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-kbl3/igt@kms_setmode@basic.html
* igt@perf_pmu@semaphore-busy@rcs0:
- shard-kbl: [PASS][41] -> [FAIL][42] ([i915#1820])
[41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-kbl4/igt@perf_pmu@semaphore-busy@rcs0.html
[42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-kbl1/igt@perf_pmu@semaphore-busy@rcs0.html
#### Possible fixes ####
* igt@gem_exec_whisper@basic-queues-priority:
- shard-glk: [DMESG-WARN][43] ([i915#118] / [i915#95]) -> [PASS][44]
[43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-glk2/igt@gem_exec_whisper@basic-queues-priority.html
[44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-glk5/igt@gem_exec_whisper@basic-queues-priority.html
* igt@gem_exec_whisper@basic-sync:
- shard-hsw: [DMESG-WARN][45] ([i915#1982]) -> [PASS][46]
[45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-hsw6/igt@gem_exec_whisper@basic-sync.html
[46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-hsw4/igt@gem_exec_whisper@basic-sync.html
* igt@gem_mmap_gtt@cpuset-big-copy:
- shard-iclb: [DMESG-WARN][47] ([i915#1982]) -> [PASS][48]
[47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-iclb2/igt@gem_mmap_gtt@cpuset-big-copy.html
[48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb4/igt@gem_mmap_gtt@cpuset-big-copy.html
* igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2:
- shard-glk: [FAIL][49] ([i915#79]) -> [PASS][50]
[49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-glk3/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html
[50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-glk6/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html
* igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-cpu:
- shard-tglb: [DMESG-WARN][51] ([i915#1982]) -> [PASS][52] +2 similar issues
[51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-tglb1/igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-cpu.html
[52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-tglb6/igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-cpu.html
* igt@kms_hdmi_inject@inject-audio:
- shard-hsw: [INCOMPLETE][53] -> [PASS][54]
[53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-hsw7/igt@kms_hdmi_inject@inject-audio.html
[54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-hsw2/igt@kms_hdmi_inject@inject-audio.html
* igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
- shard-kbl: [DMESG-WARN][55] ([i915#180]) -> [PASS][56] +7 similar issues
[55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-kbl7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
[56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-kbl6/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
* igt@kms_psr2_su@page_flip:
- shard-iclb: [SKIP][57] ([fdo#109642] / [fdo#111068]) -> [PASS][58]
[57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-iclb8/igt@kms_psr2_su@page_flip.html
[58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb2/igt@kms_psr2_su@page_flip.html
* igt@kms_psr@psr2_cursor_plane_move:
- shard-iclb: [SKIP][59] ([fdo#109441]) -> [PASS][60] +1 similar issue
[59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-iclb1/igt@kms_psr@psr2_cursor_plane_move.html
[60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb2/igt@kms_psr@psr2_cursor_plane_move.html
* igt@kms_vblank@pipe-a-query-forked:
- shard-hsw: [TIMEOUT][61] ([i915#1958] / [i915#2119]) -> [PASS][62] +1 similar issue
[61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-hsw7/igt@kms_vblank@pipe-a-query-forked.html
[62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-hsw1/igt@kms_vblank@pipe-a-query-forked.html
* igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend:
- shard-kbl: [DMESG-WARN][63] ([i915#165]) -> [PASS][64]
[63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-kbl7/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html
[64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-kbl2/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html
* igt@perf@blocking-parameterized:
- shard-iclb: [FAIL][65] ([i915#1542]) -> [PASS][66]
[65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-iclb4/igt@perf@blocking-parameterized.html
[66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb2/igt@perf@blocking-parameterized.html
* igt@perf@polling-parameterized:
- shard-iclb: [SKIP][67] -> [PASS][68]
[67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-iclb1/igt@perf@polling-parameterized.html
[68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-iclb1/igt@perf@polling-parameterized.html
- shard-kbl: [SKIP][69] ([fdo#109271]) -> [PASS][70]
[69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-kbl1/igt@perf@polling-parameterized.html
[70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-kbl6/igt@perf@polling-parameterized.html
- shard-tglb: [SKIP][71] -> [PASS][72]
[71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-tglb3/igt@perf@polling-parameterized.html
[72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-tglb7/igt@perf@polling-parameterized.html
* igt@prime_busy@before-wait@vecs0:
- shard-hsw: [FAIL][73] -> [PASS][74]
[73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-hsw7/igt@prime_busy@before-wait@vecs0.html
[74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-hsw2/igt@prime_busy@before-wait@vecs0.html
* igt@prime_mmap@test_correct:
- shard-snb: [TIMEOUT][75] ([i915#1958] / [i915#2119]) -> [PASS][76] +3 similar issues
[75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-snb6/igt@prime_mmap@test_correct.html
[76]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-snb1/igt@prime_mmap@test_correct.html
#### Warnings ####
* igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
- shard-kbl: [DMESG-WARN][77] ([i915#180]) -> [INCOMPLETE][78] ([CI#80] / [i915#155])
[77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-kbl3/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b.html
[78]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-kbl6/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b.html
* igt@kms_psr@psr2_primary_page_flip:
- shard-snb: [TIMEOUT][79] ([i915#1958] / [i915#2119]) -> [SKIP][80] ([fdo#109271])
[79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8822/shard-snb6/igt@kms_psr@psr2_primary_page_flip.html
[80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/shard-snb1/igt@kms_psr@psr2_primary_page_flip.html
- shard-hsw: [TIMEOUT][81] ([i915#1958] / [i915#2119]) -> [SKIP][82] ([fdo#109271])
[81]: https://intel-gfx
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4837/index.html
[-- Attachment #1.2: Type: text/html, Size: 35941 bytes --]
[-- Attachment #2: Type: text/plain, Size: 154 bytes --]
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 13+ messages in thread
* [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores
2020-08-04 8:50 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
@ 2020-08-04 8:50 ` Lionel Landwerlin
0 siblings, 0 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2020-08-04 8:50 UTC (permalink / raw)
To: igt-dev
To be updated with proper drm-next snapshot.
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
include/drm-uapi/i915_drm.h | 64 ++++++++++++++++++++++++++++++++++---
1 file changed, 59 insertions(+), 5 deletions(-)
diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index 2b55af13..d38feaf2 100644
--- a/include/drm-uapi/i915_drm.h
+++ b/include/drm-uapi/i915_drm.h
@@ -55,7 +55,7 @@ extern "C" {
* cause the related events to not be seen.
*
* I915_RESET_UEVENT - Event is generated just before an attempt to reset the
- * the GPU. The value supplied with the event is always 1. NOTE: Disable
+ * GPU. The value supplied with the event is always 1. NOTE: Disable
* reset via module parameter will cause this event to not be seen.
*/
#define I915_L3_PARITY_UEVENT "L3_PARITY_ERROR"
@@ -619,6 +619,12 @@ typedef struct drm_i915_irq_wait {
*/
#define I915_PARAM_PERF_REVISION 54
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
+ * timeline syncobj through drm_i915_gem_execbuffer_ext_timeline_fences. See
+ * I915_EXEC_USE_EXTENSIONS.
+ */
+#define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
+
/* Must be kept compact -- no holes and well documented */
typedef struct drm_i915_getparam {
@@ -1046,6 +1052,38 @@ struct drm_i915_gem_exec_fence {
__u32 flags;
};
+/**
+ * See drm_i915_gem_execbuffer_ext_timeline_fences.
+ */
+#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
+
+/**
+ * This structure describes an array of drm_syncobj and associated points for
+ * timeline variants of drm_syncobj. It is invalid to append this structure to
+ * the execbuf if I915_EXEC_FENCE_ARRAY is set.
+ */
+struct drm_i915_gem_execbuffer_ext_timeline_fences {
+ struct i915_user_extension base;
+
+ /**
+ * Number of element in the handles_ptr & value_ptr arrays.
+ */
+ __u64 fence_count;
+
+ /**
+ * Pointer to an array of struct drm_i915_gem_exec_fence of length
+ * fence_count.
+ */
+ __u64 handles_ptr;
+
+ /**
+ * Pointer to an array of u64 values of length fence_count. Values
+ * must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
+ * drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+ */
+ __u64 values_ptr;
+};
+
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
@@ -1062,8 +1100,15 @@ struct drm_i915_gem_execbuffer2 {
__u32 num_cliprects;
/**
* This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
- * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
- * struct drm_i915_gem_exec_fence *fences.
+ * & I915_EXEC_USE_EXTENSIONS are not set.
+ *
+ * If I915_EXEC_FENCE_ARRAY is set, then this is a pointer to an array
+ * of struct drm_i915_gem_exec_fence and num_cliprects is the length
+ * of the array.
+ *
+ * If I915_EXEC_USE_EXTENSIONS is set, then this is a pointer to a
+ * single struct drm_i915_gem_base_execbuffer_ext and num_cliprects is
+ * 0.
*/
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (0x3f)
@@ -1181,7 +1226,16 @@ struct drm_i915_gem_execbuffer2 {
*/
#define I915_EXEC_FENCE_SUBMIT (1 << 20)
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SUBMIT << 1))
+/*
+ * Setting I915_EXEC_USE_EXTENSIONS implies that
+ * drm_i915_gem_execbuffer2.cliprects_ptr is treated as a pointer to an linked
+ * list of i915_user_extension. Each i915_user_extension node is the base of a
+ * larger structure. The list of supported structures are listed in the
+ * drm_i915_gem_execbuffer_ext enum.
+ */
+#define I915_EXEC_USE_EXTENSIONS (1 << 21)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_USE_EXTENSIONS<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
@@ -1934,7 +1988,7 @@ enum drm_i915_perf_property_id {
/**
* The value specifies which set of OA unit metrics should be
- * be configured, defining the contents of any OA unit reports.
+ * configured, defining the contents of any OA unit reports.
*
* This property is available in perf revision 1.
*/
--
2.28.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores
2020-08-03 13:58 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
@ 2020-08-03 13:58 ` Lionel Landwerlin
0 siblings, 0 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2020-08-03 13:58 UTC (permalink / raw)
To: igt-dev
To be updated with proper drm-next snapshot.
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
include/drm-uapi/i915_drm.h | 65 +++++++++++++++++++++++++++++++++++--
1 file changed, 62 insertions(+), 3 deletions(-)
diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index 2b55af13..6de897f0 100644
--- a/include/drm-uapi/i915_drm.h
+++ b/include/drm-uapi/i915_drm.h
@@ -619,6 +619,13 @@ typedef struct drm_i915_irq_wait {
*/
#define I915_PARAM_PERF_REVISION 54
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
+ * timeline syncobj through drm_i915_gem_execbuf_ext_timeline_fences. See
+ * I915_EXEC_USE_EXTENSIONS.
+ */
+#define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
+
+
/* Must be kept compact -- no holes and well documented */
typedef struct drm_i915_getparam {
@@ -1046,6 +1053,42 @@ struct drm_i915_gem_exec_fence {
__u32 flags;
};
+enum drm_i915_gem_execbuffer_ext {
+ /**
+ * See drm_i915_gem_execbuf_ext_timeline_fences.
+ */
+ DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES = 1,
+
+ DRM_I915_GEM_EXECBUFFER_EXT_MAX /* non-ABI */
+};
+
+/**
+ * This structure describes an array of drm_syncobj and associated points for
+ * timeline variants of drm_syncobj. It is invalid to append this structure to
+ * the execbuf if I915_EXEC_FENCE_ARRAY is set.
+ */
+struct drm_i915_gem_execbuffer_ext_timeline_fences {
+ struct i915_user_extension base;
+
+ /**
+ * Number of element in the handles_ptr & value_ptr arrays.
+ */
+ __u64 fence_count;
+
+ /**
+ * Pointer to an array of struct drm_i915_gem_exec_fence of length
+ * fence_count.
+ */
+ __u64 handles_ptr;
+
+ /**
+ * Pointer to an array of u64 values of length fence_count. Values
+ * must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
+ * drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+ */
+ __u64 values_ptr;
+};
+
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
@@ -1062,8 +1105,15 @@ struct drm_i915_gem_execbuffer2 {
__u32 num_cliprects;
/**
* This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
- * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
- * struct drm_i915_gem_exec_fence *fences.
+ * & I915_EXEC_USE_EXTENSIONS are not set.
+ *
+ * If I915_EXEC_FENCE_ARRAY is set, then this is a pointer to an array
+ * of struct drm_i915_gem_exec_fence and num_cliprects is the length
+ * of the array.
+ *
+ * If I915_EXEC_USE_EXTENSIONS is set, then this is a pointer to a
+ * single struct drm_i915_gem_base_execbuffer_ext and num_cliprects is
+ * 0.
*/
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (0x3f)
@@ -1181,7 +1231,16 @@ struct drm_i915_gem_execbuffer2 {
*/
#define I915_EXEC_FENCE_SUBMIT (1 << 20)
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SUBMIT << 1))
+/*
+ * Setting I915_EXEC_USE_EXTENSIONS implies that
+ * drm_i915_gem_execbuffer2.cliprects_ptr is treated as a pointer to an linked
+ * list of i915_user_extension. Each i915_user_extension node is the base of a
+ * larger structure. The list of supported structures are listed in the
+ * drm_i915_gem_execbuffer_ext enum.
+ */
+#define I915_EXEC_USE_EXTENSIONS (1 << 21)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_USE_EXTENSIONS<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
--
2.28.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores
2020-08-03 9:00 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
@ 2020-08-03 9:00 ` Lionel Landwerlin
0 siblings, 0 replies; 13+ messages in thread
From: Lionel Landwerlin @ 2020-08-03 9:00 UTC (permalink / raw)
To: igt-dev
To be updated with proper drm-next snapshot.
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
include/drm-uapi/i915_drm.h | 65 +++++++++++++++++++++++++++++++++++--
1 file changed, 62 insertions(+), 3 deletions(-)
diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index 2b55af13..6de897f0 100644
--- a/include/drm-uapi/i915_drm.h
+++ b/include/drm-uapi/i915_drm.h
@@ -619,6 +619,13 @@ typedef struct drm_i915_irq_wait {
*/
#define I915_PARAM_PERF_REVISION 54
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
+ * timeline syncobj through drm_i915_gem_execbuf_ext_timeline_fences. See
+ * I915_EXEC_USE_EXTENSIONS.
+ */
+#define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
+
+
/* Must be kept compact -- no holes and well documented */
typedef struct drm_i915_getparam {
@@ -1046,6 +1053,42 @@ struct drm_i915_gem_exec_fence {
__u32 flags;
};
+enum drm_i915_gem_execbuffer_ext {
+ /**
+ * See drm_i915_gem_execbuf_ext_timeline_fences.
+ */
+ DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES = 1,
+
+ DRM_I915_GEM_EXECBUFFER_EXT_MAX /* non-ABI */
+};
+
+/**
+ * This structure describes an array of drm_syncobj and associated points for
+ * timeline variants of drm_syncobj. It is invalid to append this structure to
+ * the execbuf if I915_EXEC_FENCE_ARRAY is set.
+ */
+struct drm_i915_gem_execbuffer_ext_timeline_fences {
+ struct i915_user_extension base;
+
+ /**
+ * Number of element in the handles_ptr & value_ptr arrays.
+ */
+ __u64 fence_count;
+
+ /**
+ * Pointer to an array of struct drm_i915_gem_exec_fence of length
+ * fence_count.
+ */
+ __u64 handles_ptr;
+
+ /**
+ * Pointer to an array of u64 values of length fence_count. Values
+ * must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
+ * drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+ */
+ __u64 values_ptr;
+};
+
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
@@ -1062,8 +1105,15 @@ struct drm_i915_gem_execbuffer2 {
__u32 num_cliprects;
/**
* This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
- * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
- * struct drm_i915_gem_exec_fence *fences.
+ * & I915_EXEC_USE_EXTENSIONS are not set.
+ *
+ * If I915_EXEC_FENCE_ARRAY is set, then this is a pointer to an array
+ * of struct drm_i915_gem_exec_fence and num_cliprects is the length
+ * of the array.
+ *
+ * If I915_EXEC_USE_EXTENSIONS is set, then this is a pointer to a
+ * single struct drm_i915_gem_base_execbuffer_ext and num_cliprects is
+ * 0.
*/
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (0x3f)
@@ -1181,7 +1231,16 @@ struct drm_i915_gem_execbuffer2 {
*/
#define I915_EXEC_FENCE_SUBMIT (1 << 20)
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SUBMIT << 1))
+/*
+ * Setting I915_EXEC_USE_EXTENSIONS implies that
+ * drm_i915_gem_execbuffer2.cliprects_ptr is treated as a pointer to an linked
+ * list of i915_user_extension. Each i915_user_extension node is the base of a
+ * larger structure. The list of supported structures are listed in the
+ * drm_i915_gem_execbuffer_ext enum.
+ */
+#define I915_EXEC_USE_EXTENSIONS (1 << 21)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_USE_EXTENSIONS<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
--
2.28.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores
2020-07-08 13:20 ` [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores Lionel Landwerlin
@ 2020-07-29 12:41 ` daniel
0 siblings, 0 replies; 13+ messages in thread
From: daniel @ 2020-07-29 12:41 UTC (permalink / raw)
Cc: igt-dev
On Wed, Jul 08, 2020 at 04:20:11PM +0300, Lionel Landwerlin wrote:
> To be updated with proper drm-next snapshot.
I'm assuming you'll respin this with the right sha1 once the kernel side
has made it into drm-next? With that
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
> include/drm-uapi/i915_drm.h | 65 +++++++++++++++++++++++++++++++++++--
> 1 file changed, 62 insertions(+), 3 deletions(-)
>
> diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
> index 2b55af13..6de897f0 100644
> --- a/include/drm-uapi/i915_drm.h
> +++ b/include/drm-uapi/i915_drm.h
> @@ -619,6 +619,13 @@ typedef struct drm_i915_irq_wait {
> */
> #define I915_PARAM_PERF_REVISION 54
>
> +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
> + * timeline syncobj through drm_i915_gem_execbuf_ext_timeline_fences. See
> + * I915_EXEC_USE_EXTENSIONS.
> + */
> +#define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
> +
> +
> /* Must be kept compact -- no holes and well documented */
>
> typedef struct drm_i915_getparam {
> @@ -1046,6 +1053,42 @@ struct drm_i915_gem_exec_fence {
> __u32 flags;
> };
>
> +enum drm_i915_gem_execbuffer_ext {
> + /**
> + * See drm_i915_gem_execbuf_ext_timeline_fences.
> + */
> + DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES = 1,
> +
> + DRM_I915_GEM_EXECBUFFER_EXT_MAX /* non-ABI */
> +};
> +
> +/**
> + * This structure describes an array of drm_syncobj and associated points for
> + * timeline variants of drm_syncobj. It is invalid to append this structure to
> + * the execbuf if I915_EXEC_FENCE_ARRAY is set.
> + */
> +struct drm_i915_gem_execbuffer_ext_timeline_fences {
> + struct i915_user_extension base;
> +
> + /**
> + * Number of element in the handles_ptr & value_ptr arrays.
> + */
> + __u64 fence_count;
> +
> + /**
> + * Pointer to an array of struct drm_i915_gem_exec_fence of length
> + * fence_count.
> + */
> + __u64 handles_ptr;
> +
> + /**
> + * Pointer to an array of u64 values of length fence_count. Values
> + * must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
> + * drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
> + */
> + __u64 values_ptr;
> +};
> +
> struct drm_i915_gem_execbuffer2 {
> /**
> * List of gem_exec_object2 structs
> @@ -1062,8 +1105,15 @@ struct drm_i915_gem_execbuffer2 {
> __u32 num_cliprects;
> /**
> * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
> - * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
> - * struct drm_i915_gem_exec_fence *fences.
> + * & I915_EXEC_USE_EXTENSIONS are not set.
> + *
> + * If I915_EXEC_FENCE_ARRAY is set, then this is a pointer to an array
> + * of struct drm_i915_gem_exec_fence and num_cliprects is the length
> + * of the array.
> + *
> + * If I915_EXEC_USE_EXTENSIONS is set, then this is a pointer to a
> + * single struct drm_i915_gem_base_execbuffer_ext and num_cliprects is
> + * 0.
> */
> __u64 cliprects_ptr;
> #define I915_EXEC_RING_MASK (0x3f)
> @@ -1181,7 +1231,16 @@ struct drm_i915_gem_execbuffer2 {
> */
> #define I915_EXEC_FENCE_SUBMIT (1 << 20)
>
> -#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SUBMIT << 1))
> +/*
> + * Setting I915_EXEC_USE_EXTENSIONS implies that
> + * drm_i915_gem_execbuffer2.cliprects_ptr is treated as a pointer to an linked
> + * list of i915_user_extension. Each i915_user_extension node is the base of a
> + * larger structure. The list of supported structures are listed in the
> + * drm_i915_gem_execbuffer_ext enum.
> + */
> +#define I915_EXEC_USE_EXTENSIONS (1 << 21)
> +
> +#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_USE_EXTENSIONS<<1))
>
> #define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
> #define i915_execbuffer2_set_context_id(eb2, context) \
> --
> 2.27.0
>
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 13+ messages in thread
* [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores
2020-07-08 13:20 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
@ 2020-07-08 13:20 ` Lionel Landwerlin
2020-07-29 12:41 ` daniel
0 siblings, 1 reply; 13+ messages in thread
From: Lionel Landwerlin @ 2020-07-08 13:20 UTC (permalink / raw)
To: igt-dev
To be updated with proper drm-next snapshot.
---
include/drm-uapi/i915_drm.h | 65 +++++++++++++++++++++++++++++++++++--
1 file changed, 62 insertions(+), 3 deletions(-)
diff --git a/include/drm-uapi/i915_drm.h b/include/drm-uapi/i915_drm.h
index 2b55af13..6de897f0 100644
--- a/include/drm-uapi/i915_drm.h
+++ b/include/drm-uapi/i915_drm.h
@@ -619,6 +619,13 @@ typedef struct drm_i915_irq_wait {
*/
#define I915_PARAM_PERF_REVISION 54
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
+ * timeline syncobj through drm_i915_gem_execbuf_ext_timeline_fences. See
+ * I915_EXEC_USE_EXTENSIONS.
+ */
+#define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
+
+
/* Must be kept compact -- no holes and well documented */
typedef struct drm_i915_getparam {
@@ -1046,6 +1053,42 @@ struct drm_i915_gem_exec_fence {
__u32 flags;
};
+enum drm_i915_gem_execbuffer_ext {
+ /**
+ * See drm_i915_gem_execbuf_ext_timeline_fences.
+ */
+ DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES = 1,
+
+ DRM_I915_GEM_EXECBUFFER_EXT_MAX /* non-ABI */
+};
+
+/**
+ * This structure describes an array of drm_syncobj and associated points for
+ * timeline variants of drm_syncobj. It is invalid to append this structure to
+ * the execbuf if I915_EXEC_FENCE_ARRAY is set.
+ */
+struct drm_i915_gem_execbuffer_ext_timeline_fences {
+ struct i915_user_extension base;
+
+ /**
+ * Number of element in the handles_ptr & value_ptr arrays.
+ */
+ __u64 fence_count;
+
+ /**
+ * Pointer to an array of struct drm_i915_gem_exec_fence of length
+ * fence_count.
+ */
+ __u64 handles_ptr;
+
+ /**
+ * Pointer to an array of u64 values of length fence_count. Values
+ * must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
+ * drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+ */
+ __u64 values_ptr;
+};
+
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
@@ -1062,8 +1105,15 @@ struct drm_i915_gem_execbuffer2 {
__u32 num_cliprects;
/**
* This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
- * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
- * struct drm_i915_gem_exec_fence *fences.
+ * & I915_EXEC_USE_EXTENSIONS are not set.
+ *
+ * If I915_EXEC_FENCE_ARRAY is set, then this is a pointer to an array
+ * of struct drm_i915_gem_exec_fence and num_cliprects is the length
+ * of the array.
+ *
+ * If I915_EXEC_USE_EXTENSIONS is set, then this is a pointer to a
+ * single struct drm_i915_gem_base_execbuffer_ext and num_cliprects is
+ * 0.
*/
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (0x3f)
@@ -1181,7 +1231,16 @@ struct drm_i915_gem_execbuffer2 {
*/
#define I915_EXEC_FENCE_SUBMIT (1 << 20)
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SUBMIT << 1))
+/*
+ * Setting I915_EXEC_USE_EXTENSIONS implies that
+ * drm_i915_gem_execbuffer2.cliprects_ptr is treated as a pointer to an linked
+ * list of i915_user_extension. Each i915_user_extension node is the base of a
+ * larger structure. The list of supported structures are listed in the
+ * drm_i915_gem_execbuffer_ext enum.
+ */
+#define I915_EXEC_USE_EXTENSIONS (1 << 21)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_USE_EXTENSIONS<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
--
2.27.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2020-08-04 8:51 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-31 13:41 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 2/5] igt: add timeline test cases Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 3/5] tests/syncobj_timeline: add more timeline tests Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 4/5] tests/i915/exec_fence: add timeline fence tests Lionel Landwerlin
2020-07-31 13:41 ` [igt-dev] [PATCH i-g-t 5/5] tests/i915/gem_exec_fence: add engine chaining tests Lionel Landwerlin
2020-07-31 14:13 ` [igt-dev] ✓ Fi.CI.BAT: success for tests: Add timeline semaphore tests (rev2) Patchwork
2020-07-31 19:15 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
-- strict thread matches above, loose matches on Subject: below --
2020-08-04 8:50 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
2020-08-04 8:50 ` [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores Lionel Landwerlin
2020-08-03 13:58 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
2020-08-03 13:58 ` [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores Lionel Landwerlin
2020-08-03 9:00 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
2020-08-03 9:00 ` [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores Lionel Landwerlin
2020-07-08 13:20 [igt-dev] [PATCH i-g-t 0/5] tests: Add timeline semaphore tests Lionel Landwerlin
2020-07-08 13:20 ` [igt-dev] [PATCH i-g-t 1/5] drm-uapi: bump i915_drm.h for timeline semaphores Lionel Landwerlin
2020-07-29 12:41 ` daniel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.