On Mon, Jul 07, 2014 at 06:04:45PM +0100, Damien Lespiau wrote:
> From: Yi Sun <yi....@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....@intel.com>
> Cc: Yi Sun <yi....@intel.com>
> Signed-off-by: Lei Liu <lei.a....@intel.com>
> Signed-off-by: Yi Sun <yi....@intel.com>
> Signed-off-by: Damien Lespiau <damien.lesp...@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@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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to