summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-07-06 07:47:47 +0200
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-07-10 09:06:01 +0200
commit4258cc8ea26208a7e9537977df5e4b8c9dcf0e74 (patch)
treef28ae958876da296c0c57f45d75e8e400a6df06e
parent1fd51add8fbfc2974a2d0a2a20ae83cd76f0a2de (diff)
igt/kms: Do not wait for fence completion during commit
This will make the IGT tests that use fences more useful, since they can perform the waiting themselves when required. To celebrate, also add plane-use-after-nonblocking-unbind-fencing, the fence version of plane-use-after-nonblocking-unbind. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Gustavo Padovan <gustavo.padovan@collabora.com>
-rw-r--r--lib/igt_kms.c19
-rw-r--r--tests/kms_atomic_transition.c71
2 files changed, 63 insertions, 27 deletions
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 8bf56faf..6390229f 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -1698,6 +1698,7 @@ void igt_display_init(igt_display_t *display, int drm_fd)
pipe->plane_cursor = -1;
pipe->plane_primary = -1;
pipe->planes = NULL;
+ pipe->out_fence_fd = -1;
get_crtc_property(display->drm_fd, pipe->crtc_id,
"background_color",
@@ -1913,6 +1914,9 @@ static void igt_pipe_fini(igt_pipe_t *pipe)
free(pipe->planes);
pipe->planes = NULL;
+
+ if (pipe->out_fence_fd != -1)
+ close(pipe->out_fence_fd);
}
static void igt_output_fini(igt_output_t *output)
@@ -2502,7 +2506,11 @@ static void igt_atomic_prepare_crtc_commit(igt_pipe_t *pipe_obj, drmModeAtomicRe
igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_ACTIVE, !!output);
}
- pipe_obj->out_fence_fd = -1;
+ if (pipe_obj->out_fence_fd != -1) {
+ close(pipe_obj->out_fence_fd);
+ pipe_obj->out_fence_fd = -1;
+ }
+
if (pipe_obj->out_fence_requested)
{
igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_OUT_FENCE_PTR,
@@ -2607,16 +2615,9 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
if (s != COMMIT_UNIVERSAL)
pipe_obj->mode_changed = false;
- if (s == COMMIT_ATOMIC) {
+ if (s == COMMIT_ATOMIC && pipe_obj->out_fence_requested) {
pipe_obj->out_fence_requested = false;
-
- if (pipe_obj->out_fence_fd == -1)
- continue;
-
igt_assert(pipe_obj->out_fence_fd >= 0);
- igt_assert_eq(sync_fence_wait(pipe_obj->out_fence_fd, 1000), 0);
- close(pipe_obj->out_fence_fd);
- pipe_obj->out_fence_fd = -1;
}
for_each_plane_on_pipe(display, pipe, plane) {
diff --git a/tests/kms_atomic_transition.c b/tests/kms_atomic_transition.c
index 6e2b25da..e22763bd 100644
--- a/tests/kms_atomic_transition.c
+++ b/tests/kms_atomic_transition.c
@@ -377,6 +377,31 @@ static void atomic_commit(igt_display_t *display, enum pipe pipe, unsigned int f
igt_display_commit_atomic(display, flags, data);
}
+static int fd_completed(int fd)
+{
+ struct pollfd pfd = { fd, POLLIN };
+ int ret;
+
+ ret = poll(&pfd, 1, 0);
+ igt_assert(ret >= 0);
+ return ret;
+}
+
+static void wait_for_transition(igt_display_t *display, enum pipe pipe, bool nonblocking, bool fencing)
+{
+ if (fencing) {
+ int fence_fd = display->pipes[pipe].out_fence_fd;
+
+ igt_assert_neq(fd_completed(fence_fd), nonblocking);
+
+ igt_assert(sync_fence_wait(fence_fd, 30000) == 0);
+ } else {
+ igt_assert_neq(fd_completed(display->drm_fd), nonblocking);
+
+ drmHandleEvent(display->drm_fd, &drm_events);
+ }
+}
+
/*
* 1. Set primary plane to a known fb.
* 2. Make sure getcrtc returns the correct fb id.
@@ -393,14 +418,17 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
struct igt_fb fb, argb_fb, sprite_fb;
drmModeModeInfo *mode, override_mode;
igt_plane_t *plane;
- uint32_t iter_max = 1 << display->pipes[pipe].n_planes, i;
- struct plane_parms parms[display->pipes[pipe].n_planes];
+ igt_pipe_t *pipe_obj = &display->pipes[pipe];
+ uint32_t iter_max = 1 << pipe_obj->n_planes, i;
+ struct plane_parms parms[pipe_obj->n_planes];
bool skip_test = false;
- unsigned flags = DRM_MODE_PAGE_FLIP_EVENT;
+ unsigned flags = 0;
int ret;
if (fencing)
prepare_fencing(display, pipe);
+ else
+ flags |= DRM_MODE_PAGE_FLIP_EVENT;
if (nonblocking)
flags |= DRM_MODE_ATOMIC_NONBLOCK;
@@ -444,10 +472,10 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
wm_setup_plane(display, pipe, iter_max - 1, parms);
if (fencing)
- igt_pipe_request_out_fence(&display->pipes[pipe]);
+ igt_pipe_request_out_fence(pipe_obj);
ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
- if (ret != -EINVAL || display->pipes[pipe].n_planes < 3)
+ if (ret != -EINVAL || pipe_obj->n_planes < 3)
break;
ret = 0;
@@ -474,25 +502,28 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
igt_display_commit2(display, COMMIT_ATOMIC);
if (type == TRANSITION_AFTER_FREE) {
- struct pollfd pfd = { display->drm_fd, POLLIN };
+ int fence_fd = -1;
wm_setup_plane(display, pipe, 0, parms);
atomic_commit(display, pipe, flags, (void *)(unsigned long)0, fencing);
+ if (fencing) {
+ fence_fd = pipe_obj->out_fence_fd;
+ pipe_obj->out_fence_fd = -1;
+ }
for_each_plane_on_pipe(display, pipe, plane)
plane->fb_changed = true;
igt_display_commit2(display, COMMIT_ATOMIC);
- /*
- * Previous atomic commit should have completed
- * before this plane-only atomic commit.
- */
- igt_assert_eq(poll(&pfd, 1, 0), 1);
-
- drmHandleEvent(display->drm_fd, &drm_events);
-
+ if (fence_fd != -1) {
+ igt_assert(fd_completed(fence_fd));
+ close(fence_fd);
+ } else {
+ igt_assert(fd_completed(display->drm_fd));
+ wait_for_transition(display, pipe, false, fencing);
+ }
goto cleanup;
}
@@ -502,7 +533,7 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
wm_setup_plane(display, pipe, i, parms);
atomic_commit(display, pipe, flags, (void *)(unsigned long)i, fencing);
- drmHandleEvent(display->drm_fd, &drm_events);
+ wait_for_transition(display, pipe, nonblocking, fencing);
if (type == TRANSITION_MODESET_DISABLE) {
igt_output_set_pipe(output, PIPE_NONE);
@@ -510,7 +541,7 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
wm_setup_plane(display, pipe, 0, parms);
atomic_commit(display, pipe, flags, (void *) 0UL, fencing);
- drmHandleEvent(display->drm_fd, &drm_events);
+ wait_for_transition(display, pipe, nonblocking, fencing);
} else {
uint32_t j;
@@ -522,14 +553,14 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output
igt_output_override_mode(output, &override_mode);
atomic_commit(display, pipe, flags, (void *)(unsigned long) j, fencing);
- drmHandleEvent(display->drm_fd, &drm_events);
+ wait_for_transition(display, pipe, nonblocking, fencing);
wm_setup_plane(display, pipe, i, parms);
if (type == TRANSITION_MODESET)
igt_output_override_mode(output, NULL);
atomic_commit(display, pipe, flags, (void *)(unsigned long) i, fencing);
- drmHandleEvent(display->drm_fd, &drm_events);
+ wait_for_transition(display, pipe, nonblocking, fencing);
}
}
}
@@ -874,6 +905,10 @@ igt_main
for_each_pipe_with_valid_output(&display, pipe, output)
run_transition_test(&display, pipe, output, TRANSITION_AFTER_FREE, true, false);
+ igt_subtest("plane-use-after-nonblocking-unbind-fencing")
+ for_each_pipe_with_valid_output(&display, pipe, output)
+ run_transition_test(&display, pipe, output, TRANSITION_AFTER_FREE, true, true);
+
igt_subtest("plane-all-modeset-transition")
for_each_pipe_with_valid_output(&display, pipe, output)
run_transition_test(&display, pipe, output, TRANSITION_MODESET, false, false);