[Intel-gfx] [PATCH i-g-t 1/2] kms_plane: Add panning test for primary plane
Daniel Vetter
daniel at ffwll.ch
Mon Jul 7 23:10:10 CEST 2014
On Mon, Jul 07, 2014 at 06:04:45PM +0100, Damien Lespiau wrote:
> From: Yi Sun <yi.sun at intel.com>
>
> Get CRCs of a full red and a full blue surface as reference.
>
> Create a big framebuffer that is twice width and twice height as the
> current display mode.
The interesting stuff happens for framebuffers with offset > 4k (in
pixels iirc). Care to add such a subtest too on platforms that support
large enough strides (i.e. gen4+)?
-Daniel
>
> Fill the top left quarter with red, bottom right quarter with blue
> Check the scanned out image with the CRTC at position (0, 0) of the
> framebuffer and it should be the same CRC as the full red fb
> Check the scanned out image with the CRTC at position (hdisplay,
> vdisplay) and it should be the same CRC as the full blue fb
>
> v2: Fix a few things here and there (Damien)
>
> Cc: Lei Liu <lei.a.liu at intel.com>
> Cc: Yi Sun <yi.sun at intel.com>
> Signed-off-by: Lei Liu <lei.a.liu at intel.com>
> Signed-off-by: Yi Sun <yi.sun at intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>
> ---
> lib/igt_kms.c | 21 +++++++--
> lib/igt_kms.h | 4 ++
> tests/kms_plane.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 152 insertions(+), 3 deletions(-)
>
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 82bdec5..34311c8 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -979,7 +979,8 @@ static int igt_primary_plane_commit_legacy(igt_plane_t *primary,
> /* Primary planes can't be windowed when using a legacy commit */
> igt_assert((primary->crtc_x == 0 && primary->crtc_y == 0));
>
> - if (!primary->fb_changed && !primary->position_changed)
> + if (!primary->fb_changed && !primary->position_changed &&
> + !primary->panning_changed)
> return 0;
>
> crtc_id = output->config.crtc->crtc_id;
> @@ -996,13 +997,13 @@ static int igt_primary_plane_commit_legacy(igt_plane_t *primary,
> igt_output_name(output),
> pipe_name(output->config.pipe),
> fb_id,
> - 0, 0,
> + primary->pan_x, primary->pan_y,
> mode->hdisplay, mode->vdisplay);
>
> ret = drmModeSetCrtc(display->drm_fd,
> crtc_id,
> fb_id,
> - 0, 0, /* x, y */
> + primary->pan_x, primary->pan_y,
> &output->id,
> 1,
> mode);
> @@ -1254,6 +1255,20 @@ void igt_plane_set_position(igt_plane_t *plane, int x, int y)
> plane->position_changed = true;
> }
>
> +void igt_plane_set_panning(igt_plane_t *plane, int x, int y)
> +{
> + igt_pipe_t *pipe = plane->pipe;
> + igt_display_t *display = pipe->display;
> +
> + LOG(display, "%c.%d: plane_set_panning(%d,%d)\n", pipe_name(pipe->pipe),
> + plane->index, x, y);
> +
> + plane->pan_x = x;
> + plane->pan_y = y;
> +
> + plane->panning_changed = true;
> +}
> +
> void igt_wait_for_vblank(int drm_fd, enum pipe pipe)
> {
> drmVBlank wait_vbl;
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index 95ba112..a079fc2 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -113,6 +113,7 @@ typedef struct {
> unsigned int is_cursor : 1;
> unsigned int fb_changed : 1;
> unsigned int position_changed : 1;
> + unsigned int panning_changed : 1;
> /*
> * drm_plane can be NULL for primary and cursor planes (when not
> * using the atomic modeset API)
> @@ -121,6 +122,8 @@ typedef struct {
> struct igt_fb *fb;
> /* position within pipe_src_w x pipe_src_h */
> int crtc_x, crtc_y;
> + /* panning offset within the fb */
> + unsigned int pan_x, pan_y;
> } igt_plane_t;
>
> struct igt_pipe {
> @@ -170,6 +173,7 @@ igt_plane_t *igt_output_get_plane(igt_output_t *output, enum igt_plane plane);
>
> void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb);
> void igt_plane_set_position(igt_plane_t *plane, int x, int y);
> +void igt_plane_set_panning(igt_plane_t *plane, int x, int y);
>
> void igt_wait_for_vblank(int drm_fd, enum pipe pipe);
>
> diff --git a/tests/kms_plane.c b/tests/kms_plane.c
> index 45c4a77..7437641 100644
> --- a/tests/kms_plane.c
> +++ b/tests/kms_plane.c
> @@ -45,7 +45,9 @@ typedef struct {
> igt_pipe_crc_t *pipe_crc;
> } data_t;
>
> +static color_t red = { 1.0f, 0.0f, 0.0f };
> static color_t green = { 0.0f, 1.0f, 0.0f };
> +static color_t blue = { 0.0f, 0.0f, 1.0f };
>
> /*
> * Common code across all tests, acting on data_t
> @@ -211,6 +213,124 @@ test_plane_position(data_t *data, enum pipe pipe, enum igt_plane plane,
> flags);
> }
>
> +/*
> + * Plane panning test.
> + * - We start by grabbing reference CRCs of a full red and a full blue fb
> + * being scanned out on the primary plane
> + * - Then we create a big fb, sized (2 * hdisplay, 2 * vdisplay) and:
> + * - fill the top left quarter with red
> + * - fill the bottom right quarter with blue
> + * - The TEST_PANNING_TOP_LEFT test makes sure that with panning at (0, 0)
> + * we do get the same CRC than the full red fb.
> + * - The TEST_PANNING_BOTTOM_RIGHT test makes sure that with panning at
> + * (vdisplay, hdisplay) we do get the same CRC than the full blue fb.
> + */
> +typedef struct {
> + data_t *data;
> + igt_crc_t red_crc, blue_crc;
> +} test_panning_t;
> +
> +static void
> +create_fb_for_mode__panning(data_t *data, drmModeModeInfo *mode,
> + struct igt_fb *fb /* out */)
> +{
> + unsigned int fb_id;
> + cairo_t *cr;
> +
> + fb_id = igt_create_fb(data->drm_fd,
> + mode->hdisplay * 2, mode->vdisplay * 2,
> + DRM_FORMAT_XRGB8888,
> + false /* tiling */,
> + fb);
> + igt_assert(fb_id);
> +
> + cr = igt_get_cairo_ctx(data->drm_fd, fb);
> +
> + igt_paint_color(cr, 0, 0, mode->hdisplay, mode->vdisplay,
> + 1.0, 0.0, 0.0);
> +
> + igt_paint_color(cr,
> + mode->hdisplay, mode->vdisplay,
> + mode->hdisplay, mode->vdisplay,
> + 0.0, 0.0, 1.0);
> +
> + igt_assert(cairo_status(cr) == 0);
> + cairo_destroy(cr);
> +}
> +
> +enum {
> + TEST_PANNING_TOP_LEFT = 1 << 0,
> + TEST_PANNING_BOTTOM_RIGHT = 1 << 1,
> +};
> +
> +static void
> +test_plane_panning_with_output(data_t *data,
> + enum pipe pipe,
> + enum igt_plane plane,
> + igt_output_t *output,
> + unsigned int flags)
> +{
> + test_panning_t test = { .data = data };
> + igt_plane_t *primary;
> + struct igt_fb primary_fb;
> + drmModeModeInfo *mode;
> + igt_crc_t crc;
> +
> + fprintf(stdout, "Testing connector %s using pipe %c plane %d\n",
> + igt_output_name(output), pipe_name(pipe), plane);
> +
> + test_init(data, pipe);
> +
> + test_grab_crc(data, output, &red, &test.red_crc);
> + test_grab_crc(data, output, &blue, &test.blue_crc);
> +
> + igt_output_set_pipe(output, pipe);
> +
> + mode = igt_output_get_mode(output);
> + primary = igt_output_get_plane(output, 0);
> +
> + create_fb_for_mode__panning(data, mode, &primary_fb);
> + igt_plane_set_fb(primary, &primary_fb);
> +
> + if (flags & TEST_PANNING_TOP_LEFT)
> + igt_plane_set_panning(primary, 0, 0);
> + else
> + igt_plane_set_panning(primary, mode->hdisplay, mode->vdisplay);
> +
> + igt_plane_set_position(primary, 0, 0);
> +
> + igt_display_commit(&data->display);
> +
> + igt_pipe_crc_collect_crc(data->pipe_crc, &crc);
> +
> + if (flags & TEST_PANNING_TOP_LEFT)
> + igt_assert(igt_crc_equal(&test.red_crc, &crc));
> + else
> + igt_assert(igt_crc_equal(&test.blue_crc, &crc));
> +
> + igt_plane_set_fb(primary, NULL);
> +
> + /* reset states to neutral values, assumed by other tests */
> + igt_output_set_pipe(output, PIPE_ANY);
> + igt_plane_set_panning(primary, 0, 0);
> +
> + test_fini(data);
> +}
> +
> +static void
> +test_plane_panning(data_t *data, enum pipe pipe, enum igt_plane plane,
> + unsigned int flags)
> +{
> + igt_output_t *output;
> +
> + igt_skip_on(pipe >= data->display.n_pipes);
> + igt_skip_on(plane >= data->display.pipes[pipe].n_planes);
> +
> + for_each_connected_output(&data->display, output)
> + test_plane_panning_with_output(data, pipe, plane, output,
> + flags);
> +}
> +
> static void
> run_tests_for_pipe_plane(data_t *data, enum pipe pipe, enum igt_plane plane)
> {
> @@ -222,6 +342,16 @@ run_tests_for_pipe_plane(data_t *data, enum pipe pipe, enum igt_plane plane)
> igt_subtest_f("plane-position-hole-pipe-%c-plane-%d",
> pipe_name(pipe), plane)
> test_plane_position(data, pipe, plane, 0);
> +
> + igt_subtest_f("plane-panning-top-left-pipe-%c-plane-%d",
> + pipe_name(pipe), plane)
> + test_plane_panning(data, pipe, plane, TEST_PANNING_TOP_LEFT);
> +
> + igt_subtest_f("plane-panning-bottom-right-pipe-%c-plane-%d",
> + pipe_name(pipe), plane)
> + test_plane_panning(data, pipe, plane,
> + TEST_PANNING_BOTTOM_RIGHT);
> +
> }
>
> static void
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
More information about the Intel-gfx
mailing list