[Intel-gfx] [PATCH i-g-t] tests: atomic: add test to verify page flip event emissions

Daniel Vetter daniel at ffwll.ch
Fri Apr 22 12:59:36 UTC 2016


On Thu, Apr 21, 2016 at 05:01:31PM +0100, Lionel Landwerlin wrote:
> It seems we don't have a test verifying events with atomic commits
> yet. Here is a first step.
> 
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>

Feel like also making a testcase variant for the other cases of crtc's
ACTIVE property?
- off -> off: kernel should reject event generation
- off -> on: kernel should generate event, and the frame counter should be
  just a few frames less (at most) than what you get from the vblank ioctl
  right after the modeset completes
- on -> off: same as off -> on but in reverse

Would be awesome ...
-Daniel

> ---
>  tests/kms_atomic.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 127 insertions(+), 10 deletions(-)
> 
> diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
> index f27ee46..bc75108 100644
> --- a/tests/kms_atomic.c
> +++ b/tests/kms_atomic.c
> @@ -252,10 +252,10 @@ static uint32_t blob_duplicate(int fd, uint32_t id_orig)
>  	plane_check_current_state(plane_old, relax); \
>  }
>  
> -#define plane_commit_atomic(plane, req, relax) { \
> +#define plane_commit_atomic(plane, req, flags, relax) {	\
>  	drmModeAtomicSetCursor(req, 0); \
>  	plane_populate_req(plane, req); \
> -	do_atomic_commit((plane)->state->desc->fd, req, 0); \
> +	do_atomic_commit((plane)->state->desc->fd, req, flags); \
>  	plane_check_current_state(plane, relax); \
>  }
>  
> @@ -886,10 +886,10 @@ static void plane_overlay(struct kms_atomic_crtc_state *crtc,
>  
>  	/* Enable the overlay plane using the atomic API, and double-check
>  	 * state is what we think it should be. */
> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
> +	plane_commit_atomic(&plane, req, 0, ATOMIC_RELAX_NONE);
>  
>  	/* Disable the plane and check the state matches the old. */
> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
> +	plane_commit_atomic(plane_old, req, 0, ATOMIC_RELAX_NONE);
>  
>  	/* Re-enable the plane through the legacy plane API, and verify through
>  	 * atomic. */
> @@ -983,10 +983,10 @@ static void plane_cursor(struct kms_atomic_crtc_state *crtc,
>  
>  	/* Flip the cursor plane using the atomic API, and double-check
>  	 * state is what we think it should be. */
> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
> +	plane_commit_atomic(&plane, req, 0, ATOMIC_RELAX_NONE);
>  
>  	/* Restore the cursor plane and check the state matches the old. */
> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
> +	plane_commit_atomic(plane_old, req, 0, ATOMIC_RELAX_NONE);
>  
>  	/* Re-enable the plane through the legacy cursor API, and verify
>  	 * through atomic. */
> @@ -1010,7 +1010,7 @@ static void plane_cursor(struct kms_atomic_crtc_state *crtc,
>  	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
>  
>  	/* Finally, restore to the original state. */
> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
> +	plane_commit_atomic(plane_old, req, 0, ATOMIC_RELAX_NONE);
>  
>  	drmModeAtomicFree(req);
>  }
> @@ -1043,7 +1043,7 @@ static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
>  	                        ATOMIC_RELAX_NONE, EINVAL);
>  
>  	plane.fb_id = plane_old->fb_id;
> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
> +	plane_commit_atomic(&plane, req, 0, ATOMIC_RELAX_NONE);
>  
>  	/* Pass a series of invalid object IDs for the CRTC ID. */
>  	plane.crtc_id = plane.obj;
> @@ -1063,7 +1063,7 @@ static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
>  	                        ATOMIC_RELAX_NONE, EINVAL);
>  
>  	plane.crtc_id = plane_old->crtc_id;
> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
> +	plane_commit_atomic(&plane, req, 0, ATOMIC_RELAX_NONE);
>  
>  	/* Create a framebuffer too small for the plane configuration. */
>  	igt_require(format != 0);
> @@ -1085,7 +1085,7 @@ static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
>  	                        ATOMIC_RELAX_NONE, ENOSPC);
>  
>  	/* Restore the primary plane and check the state matches the old. */
> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
> +	plane_commit_atomic(plane_old, req, 0, ATOMIC_RELAX_NONE);
>  
>  	drmModeAtomicFree(req);
>  }
> @@ -1280,6 +1280,112 @@ static void atomic_invalid_params(struct kms_atomic_crtc_state *crtc,
>  	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
>  }
>  
> +static void get_events(struct kms_atomic_crtc_state *crtc,
> +		       int *page_flips,
> +		       int *vblank_count,
> +		       int msec)
> +{
> +	struct kms_atomic_desc *desc = crtc->state->desc;
> +	struct timeval timeout = { .tv_sec = 0, .tv_usec = msec * 1000 };
> +	fd_set fds;
> +	char buffer[1024];
> +	int idx, len, ret;
> +
> +	FD_ZERO(&fds);
> +	FD_SET(desc->fd, &fds);
> +
> +	ret = select(1, &fds, NULL, NULL, &timeout);
> +	if (ret < 1)
> +		return;
> +
> +	len = read(desc->fd, buffer, sizeof(buffer));
> +	if (len == 0)
> +		return;
> +
> +	idx = 0;
> +	while (idx < len) {
> +		struct drm_event event;
> +
> +		igt_assert_lte(sizeof(event), len - idx);
> +
> +		memcpy(&event, &buffer[idx], sizeof(event));
> +		switch (event.type) {
> +		case DRM_EVENT_FLIP_COMPLETE:
> +			(*page_flips)++;
> +			break;
> +		case DRM_EVENT_VBLANK:
> +			(*vblank_count)++;
> +			break;
> +		default:
> +			break;
> +		}
> +
> +		idx += event.length;
> +	}
> +}
> +
> +static void plane_pageflip_events(struct kms_atomic_crtc_state *crtc,
> +				  struct kms_atomic_plane_state *plane_old)
> +{
> +	struct drm_mode_modeinfo *mode = crtc->mode.data;
> +	struct kms_atomic_plane_state plane = *plane_old;
> +	uint32_t format = plane_get_igt_format(&plane);
> +	drmModeAtomicReq *req = drmModeAtomicAlloc();
> +	struct igt_fb fb[2];
> +	int i, pageflip_count = 0, vblank_count = 0;
> +	int flags = DRM_MODE_PAGE_FLIP_EVENT;
> +
> +	igt_require(format != 0);
> +
> +	for (i = 0; i < ARRAY_SIZE(fb); i++)
> +		igt_create_pattern_fb(plane.state->desc->fd,
> +				      plane.crtc_w, plane.crtc_h,
> +				      format, I915_TILING_NONE, &fb[i]);
> +
> +	plane.src_x = 0;
> +	plane.src_y = 0;
> +	plane.src_w = mode->hdisplay << 16;
> +	plane.src_h = mode->vdisplay << 16;
> +	plane.crtc_x = 0;
> +	plane.crtc_y = 0;
> +	plane.crtc_w = mode->hdisplay;
> +	plane.crtc_h = mode->vdisplay;
> +	plane.crtc_id = crtc->obj;
> +	plane.fb_id = fb[0].fb_id;
> +
> +	/* Flip the primary plane using the atomic API, and double-check
> +	 * state is what we think it should be. */
> +	crtc_commit_atomic(crtc, &plane, req, ATOMIC_RELAX_NONE);
> +
> +	get_events(crtc, &pageflip_count, &vblank_count, 0);
> +	igt_assert_eq(1, pageflip_count);
> +
> +	drmModeAtomicFree(req);
> +	req = drmModeAtomicAlloc();
> +
> +	/* Change the framebuffer on the plane, we should get one
> +	 * pageflip event. */
> +	plane.fb_id = fb[1].fb_id;
> +	plane_commit_atomic(&plane, req, flags, ATOMIC_RELAX_NONE);
> +	get_events(crtc, &pageflip_count, &vblank_count, 20);
> +	igt_assert_eq(2, pageflip_count);
> +
> +	/* No change, page flip event count should remain the same. */
> +	plane.fb_id = fb[1].fb_id;
> +	plane_commit_atomic(&plane, req, flags, ATOMIC_RELAX_NONE);
> +	get_events(crtc, &pageflip_count, &vblank_count, 20);
> +	igt_assert_eq(2, pageflip_count);
> +
> +	/* Change back the plane's framebuffer to its original one, we
> +	 * should get a page flip event. */
> +	plane.fb_id = fb[0].fb_id;
> +	plane_commit_atomic(&plane, req, flags, ATOMIC_RELAX_NONE);
> +	get_events(crtc, &pageflip_count, &vblank_count, 20);
> +	igt_assert_eq(3, pageflip_count);
> +
> +	drmModeAtomicFree(req);
> +}
> +
>  igt_main
>  {
>  	struct kms_atomic_desc desc;
> @@ -1373,6 +1479,17 @@ igt_main
>  		atomic_state_free(scratch);
>  	}
>  
> +	igt_subtest("atomic_pageflip_events") {
> +		struct kms_atomic_state *scratch = atomic_state_dup(current);
> +		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
> +		struct kms_atomic_plane_state *plane =
> +			find_plane(scratch, PLANE_TYPE_PRIMARY, crtc);
> +
> +		igt_require(plane);
> +		plane_pageflip_events(crtc, plane);
> +		atomic_state_free(scratch);
> +	}
> +
>  	atomic_state_free(current);
>  
>  	igt_fixture
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the Intel-gfx mailing list