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.lankho...@linux.intel.com>
---
 lib/igt_kms.c                 | 19 ++++++------
 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 8bf56faf41e9..6390229f1546 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 6e2b25da75db..e22763bdf94b 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);
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to