@@ -2543,6 +2543,8 @@ int igt_display_try_commit_atomic(igt_display_t *display, uint32_t flags, void *
* @display: #igt_display_t to commit.
* @flags: Flags passed to drmModeAtomicCommit.
* @user_data: User defined pointer passed to drmModeAtomicCommit.
+ * @with_test: test atomic commit with DRM_MODE_ATOMIC_TEST_ONLY
+ * flag before actual atomic commit.
*
* This function is similar to #igt_display_commit2, but is
* used when you want to pass different flags to the actual commit.
@@ -2554,13 +2556,35 @@ int igt_display_try_commit_atomic(igt_display_t *display, uint32_t flags, void *
* @user_data is returned in the event if you pass
* DRM_MODE_PAGE_FLIP_EVENT to @flags.
*
- * This function will abort the test if commit fails.
+ * This function will return an error if commit fails.
*/
-void igt_display_commit_atomic(igt_display_t *display, uint32_t flags, void *user_data)
+int igt_display_commit_atomic(igt_display_t *display, uint32_t flags,
+ void *user_data, bool with_test)
{
- int ret = igt_display_try_commit_atomic(display, flags, user_data);
+ int ret;
+ bool page_flip_event;
- igt_assert_eq(ret, 0);
+ if (with_test) {
+ flags |= DRM_MODE_ATOMIC_TEST_ONLY;
+ page_flip_event = flags & DRM_MODE_PAGE_FLIP_EVENT;
+
+ if (page_flip_event)
+ flags &= ~DRM_MODE_PAGE_FLIP_EVENT;
+
+ ret = igt_display_try_commit_atomic(display, flags, user_data);
+ igt_assert(ret != -EINVAL);
+
+ flags &= ~DRM_MODE_ATOMIC_TEST_ONLY;
+
+ if (page_flip_event)
+ flags |= DRM_MODE_PAGE_FLIP_EVENT;
+
+ ret = igt_display_try_commit_atomic(display, flags, user_data);
+ } else {
+ ret = igt_display_try_commit_atomic(display, flags, user_data);
+ }
+
+ return ret;
}
/**
@@ -359,7 +359,8 @@ void igt_display_fini(igt_display_t *display);
int igt_display_commit2(igt_display_t *display, enum igt_commit_style s);
int igt_display_commit(igt_display_t *display);
int igt_display_try_commit_atomic(igt_display_t *display, uint32_t flags, void *user_data);
-void igt_display_commit_atomic(igt_display_t *display, uint32_t flags, void *user_data);
+int igt_display_commit_atomic(igt_display_t *display, uint32_t flags,
+ void *user_data, bool with_test);
int igt_display_try_commit2(igt_display_t *display, enum igt_commit_style s);
int igt_display_get_n_pipes(igt_display_t *display);
@@ -79,9 +79,9 @@ static bool skip_on_unsupported_nonblocking_modeset(igt_display_t *display)
* unsupported -EINVAL is returned. If the second commit returns
* -EINVAL, it's from not being able to support nonblocking modeset.
*/
- igt_display_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
-
- ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK, NULL);
+ ret = igt_display_commit_atomic(display,
+ DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK,
+ NULL, true);
if (ret == -EINVAL)
return true;
@@ -276,6 +276,7 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
struct plane_parms parms[IGT_MAX_PLANES];
bool skip_test = false;
unsigned flags = DRM_MODE_PAGE_FLIP_EVENT;
+ int ret;
if (nonblocking)
flags |= DRM_MODE_ATOMIC_NONBLOCK;
@@ -315,7 +316,8 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
wm_setup_plane(display, pipe, i, parms);
- igt_display_commit_atomic(display, flags, (void *)(unsigned long)i);
+ ret = igt_display_commit_atomic(display, flags, (void *)(unsigned long)i, true);
+ igt_assert_eq(ret, 0);
drmHandleEvent(display->drm_fd, &drm_events);
if (type == TRANSITION_MODESET_DISABLE) {
@@ -323,8 +325,8 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
wm_setup_plane(display, pipe, 0, parms);
- igt_display_commit_atomic(display, flags, (void *)0UL);
-
+ ret = igt_display_commit_atomic(display, flags, (void *)0UL, true);
+ igt_assert_eq(ret, 0);
drmHandleEvent(display->drm_fd, &drm_events);
} else {
uint32_t j;
@@ -336,14 +338,16 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
if (type == TRANSITION_MODESET)
igt_output_override_mode(output, &override_mode);
- igt_display_commit_atomic(display, flags, (void *)(unsigned long)j);
+ ret = igt_display_commit_atomic(display, flags, (void *)(unsigned long)j, true);
+ igt_assert_eq(ret, 0);
drmHandleEvent(display->drm_fd, &drm_events);
wm_setup_plane(display, pipe, i, parms);
if (type == TRANSITION_MODESET)
igt_output_override_mode(output, NULL);
- igt_display_commit_atomic(display, flags, (void *)(unsigned long)i);
+ ret = igt_display_commit_atomic(display, flags, (void *)(unsigned long)i, true);
+ igt_assert_eq(ret, 0);
drmHandleEvent(display->drm_fd, &drm_events);
}
}
@@ -374,7 +378,8 @@ static void commit_display(igt_display_t *display, unsigned event_mask, bool non
if (nonblocking)
flags |= DRM_MODE_ATOMIC_NONBLOCK;
- igt_display_commit_atomic(display, flags, NULL);
+ ret = igt_display_commit_atomic(display, flags, NULL, true);
+ igt_assert_eq(ret, 0);
igt_debug("Event mask: %x, waiting for %i events\n", event_mask, num_events);
@@ -97,6 +97,7 @@ static void flip_to_fb(igt_display_t *dpy, int pipe,
struct pollfd pfd = { .fd = dpy->drm_fd, .events = POLLIN };
struct timespec tv = { 1, 0 };
struct drm_event_vblank ev;
+ int ret;
igt_spin_t *t = igt_spin_batch_new(dpy->drm_fd, ring, fb->gem_handle);
igt_fork(child, 1) {
@@ -108,10 +109,11 @@ static void flip_to_fb(igt_display_t *dpy, int pipe,
else {
igt_plane_set_fb(igt_output_get_plane(output, IGT_PLANE_PRIMARY), fb);
igt_output_set_pipe(output, PIPE_NONE);
- igt_display_commit_atomic(dpy,
- DRM_MODE_ATOMIC_NONBLOCK |
- DRM_MODE_PAGE_FLIP_EVENT |
- DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+ ret = igt_display_commit_atomic(dpy,
+ DRM_MODE_ATOMIC_NONBLOCK |
+ DRM_MODE_PAGE_FLIP_EVENT |
+ DRM_MODE_ATOMIC_ALLOW_MODESET, NULL, true);
+ igt_assert_eq(ret, 0);
}
kill(getppid(), SIGALRM);
@@ -191,20 +193,23 @@ static void test_atomic_commit_hang(igt_display_t *dpy, igt_plane_t *primary,
struct pollfd pfd = { .fd = dpy->drm_fd, .events = POLLIN };
unsigned flags = 0;
struct drm_event_vblank ev;
-
+ int ret;
+
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
flags |= DRM_MODE_ATOMIC_NONBLOCK;
flags |= DRM_MODE_PAGE_FLIP_EVENT;
- igt_display_commit_atomic(dpy, flags, NULL);
-
+ ret = igt_display_commit_atomic(dpy, flags, NULL, true);
+ igt_assert_eq(ret, 0);
+
igt_fork(child, 1) {
/*
* bit of a hack, just set atomic commit to NULL fb to make sure
* that we don't wait for the new update to complete.
*/
igt_plane_set_fb(primary, NULL);
- igt_display_commit_atomic(dpy, 0, NULL);
+ ret = igt_display_commit_atomic(dpy, 0, NULL, true);
+ igt_assert_eq(ret, 0);
if (completes_early)
igt_assert(gem_bo_busy(dpy->drm_fd, busy_fb->gem_handle));
@@ -253,6 +253,7 @@ static enum pipe find_connected_pipe(igt_display_t *display, bool second)
static void flip_nonblocking(igt_display_t *display, enum pipe pipe, bool atomic, struct igt_fb *fb)
{
igt_plane_t *primary = &display->pipes[pipe].planes[IGT_PLANE_PRIMARY];
+ int ret;
if (!atomic) {
/* Schedule a nonblocking flip for the next vblank */
@@ -260,7 +261,8 @@ static void flip_nonblocking(igt_display_t *display, enum pipe pipe, bool atomic
DRM_MODE_PAGE_FLIP_EVENT, fb));
} else {
igt_plane_set_fb(primary, fb);
- igt_display_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, fb);
+ ret = igt_display_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, fb, true);
+ igt_assert_eq(ret, 0);
}
}
@@ -304,17 +306,16 @@ static void transition_nonblocking(igt_display_t *display, enum pipe pipe,
{
igt_plane_t *primary = &display->pipes[pipe].planes[IGT_PLANE_PRIMARY];
igt_plane_t *sprite = &display->pipes[pipe].planes[IGT_PLANE_2];
+ int ret;
if (hide_sprite) {
igt_plane_set_fb(primary, prim_fb);
igt_plane_set_fb(sprite, NULL);
} else {
- int ret;
-
igt_plane_set_fb(primary, NULL);
igt_plane_set_fb(sprite, argb_fb);
- ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, display);
+ ret = igt_display_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, display, true);
if (!ret)
return;
@@ -322,7 +323,8 @@ static void transition_nonblocking(igt_display_t *display, enum pipe pipe,
igt_plane_set_fb(sprite, prim_fb);
}
- igt_display_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, display);
+ ret = igt_display_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, display, true);
+ igt_assert_eq(ret, 0);
}
static void prepare_flip_test(igt_display_t *display,
@@ -835,9 +837,7 @@ static bool skip_on_unsupported_nonblocking_modeset(igt_display_t *display)
enum pipe pipe;
int ret;
- igt_display_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
-
- ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK, NULL);
+ ret = igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK, NULL, true);
if (ret == -EINVAL)
return true;
@@ -859,6 +859,7 @@ static void nonblocking_modeset_vs_cursor(igt_display_t *display, int loops)
struct drm_mode_cursor arg[2];
bool skip_test;
igt_plane_t *cursor = NULL, *plane;
+ int ret;
igt_require(display->is_atomic);
igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
@@ -904,7 +905,8 @@ static void nonblocking_modeset_vs_cursor(igt_display_t *display, int loops)
igt_output_set_pipe(output, pipe);
igt_plane_set_fb(cursor, NULL);
- igt_display_commit_atomic(display, flags, NULL);
+ ret = igt_display_commit_atomic(display, flags, NULL, true);
+ igt_assert_eq(ret, 0);
igt_assert_eq(0, poll(&pfd, 1, 0));
igt_assert_eq(0, pfd.revents);
@@ -919,7 +921,8 @@ static void nonblocking_modeset_vs_cursor(igt_display_t *display, int loops)
igt_reset_timeout();
igt_output_set_pipe(output, PIPE_NONE);
- igt_display_commit_atomic(display, flags, NULL);
+ ret = igt_display_commit_atomic(display, flags, NULL, true);
+ igt_assert_eq(ret, 0);
igt_assert_eq(0, poll(&pfd, 1, 0));
igt_assert_eq(0, pfd.revents);
@@ -954,6 +957,7 @@ static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool
enum pipe pipe2 = find_connected_pipe(display, true);
igt_output_t *output, *output2;
bool skip_test = false;
+ int ret;
igt_fail_on(modeset && !atomic);
@@ -1010,7 +1014,8 @@ static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool
igt_plane_set_fb(igt_output_get_plane(output, IGT_PLANE_PRIMARY), &fb_info);
igt_output_set_pipe(output2, (nloops & 1) ? PIPE_NONE : pipe2);
- igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK, NULL);
+ ret = igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK, NULL, true);
+ igt_assert_eq(ret, 0);
}
igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
@@ -220,6 +220,7 @@ test_panel_fitting_fastset(igt_display_t *display, const enum pipe pipe, igt_out
igt_plane_t *primary, *sprite;
drmModeModeInfo mode;
struct igt_fb red, green, blue;
+ int ret;
igt_assert(kmstest_get_connector_default_mode(display->drm_fd, output->config.connector, &mode));
@@ -254,19 +255,22 @@ test_panel_fitting_fastset(igt_display_t *display, const enum pipe pipe, igt_out
igt_plane_set_fb(primary, &red);
/* Don't pass ALLOW_MODESET with overridden mode, force fastset. */
- igt_display_commit_atomic(display, 0, NULL);
+ ret = igt_display_commit_atomic(display, 0, NULL, true);
+ igt_assert_eq(ret, 0);
/* Test with different scaled mode */
mode.hdisplay = 800;
mode.vdisplay = 600;
igt_output_override_mode(output, &mode);
igt_plane_set_fb(primary, &green);
- igt_display_commit_atomic(display, 0, NULL);
+ ret = igt_display_commit_atomic(display, 0, NULL, true);
+ igt_assert_eq(ret, 0);
/* Restore normal mode */
igt_plane_set_fb(primary, &blue);
igt_output_override_mode(output, NULL);
- igt_display_commit_atomic(display, 0, NULL);
+ ret = igt_display_commit_atomic(display, 0, NULL, true);
+ igt_assert_eq(ret, 0);
igt_plane_set_fb(primary, NULL);
igt_output_set_pipe(output, PIPE_NONE);
@@ -244,10 +244,10 @@ test_atomic_plane_position_with_output(data_t *data, enum pipe pipe,
vblank_start = kmstest_get_vblank(data->display.drm_fd, pipe,
DRM_VBLANK_NEXTONMISS);
- igt_display_commit_atomic(&data->display,
- DRM_MODE_PAGE_FLIP_EVENT,
- &data->display);
-
+ ret = igt_display_commit_atomic(&data->display,
+ DRM_MODE_PAGE_FLIP_EVENT,
+ &data->display, true);
+ igt_assert_eq(ret, 0);
igt_set_timeout(1, "Stuck on page flip");
ret = read(data->display.drm_fd, buf, sizeof(buf));
Validate atomic commit correctness before actual commit. For: VIZ-6956 v2: Add flag to toggle TEST_ONLY for atomic commit. Remove DRM_MODE_PAGE_FLIP_EVENT flag, if enabled, before trying atomic commit with TEST_ONLY flag (Maarten) Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Mika Kahola <mika.kahola@intel.com> --- lib/igt_kms.c | 32 ++++++++++++++++++++++++++++---- lib/igt_kms.h | 3 ++- tests/kms_atomic_transition.c | 23 ++++++++++++++--------- tests/kms_busy.c | 21 +++++++++++++-------- tests/kms_cursor_legacy.c | 27 ++++++++++++++++----------- tests/kms_panel_fitting.c | 10 +++++++--- tests/kms_plane_multiple.c | 8 ++++---- 7 files changed, 84 insertions(+), 40 deletions(-)