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