diff options
author | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2017-07-06 07:47:47 +0200 |
---|---|---|
committer | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2017-07-10 09:06:01 +0200 |
commit | 4258cc8ea26208a7e9537977df5e4b8c9dcf0e74 (patch) | |
tree | f28ae958876da296c0c57f45d75e8e400a6df06e | |
parent | 1fd51add8fbfc2974a2d0a2a20ae83cd76f0a2de (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.c | 19 | ||||
-rw-r--r-- | tests/kms_atomic_transition.c | 71 |
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); |