From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Joseph Garvey <joseph1.garvey@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: igt/kms_rotation_crc: Add horizontal flip subtest.
Date: Thu, 21 Sep 2017 13:57:14 +0300 [thread overview]
Message-ID: <20170921105714.GE4914@intel.com> (raw)
In-Reply-To: <1505965837-1744-1-git-send-email-joseph1.garvey@intel.com>
On Wed, Sep 20, 2017 at 08:50:37PM -0700, Joseph Garvey wrote:
> Test that horizontal flip works with supported rotations. Includes
> a fix for the unrotated fb which was not being positioned correctly
> with portrait and landscape rectangles.
>
> Signed-off-by: Joseph Garvey <joseph1.garvey@intel.com>
> ---
> lib/igt_kms.c | 2 +-
> lib/igt_kms.h | 4 +
> tests/kms_rotation_crc.c | 197 ++++++++++++++++++++++++++++++++++++++---------
> 3 files changed, 166 insertions(+), 37 deletions(-)
>
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 7bcafc0..ec6ffd2 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -3054,7 +3054,7 @@ void igt_fb_set_size(struct igt_fb *fb, igt_plane_t *plane,
>
> static const char *rotation_name(igt_rotation_t rotation)
> {
> - switch (rotation) {
> + switch (rotation & IGT_ROTATION_MASK) {
> case IGT_ROTATION_0:
> return "0°";
> case IGT_ROTATION_90:
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index 3d1061f..61393d1 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -281,8 +281,12 @@ typedef enum {
> IGT_ROTATION_90 = 1 << 1,
> IGT_ROTATION_180 = 1 << 2,
> IGT_ROTATION_270 = 1 << 3,
> + IGT_REFLECT_X = 1 << 4,
Maybe add REFLECT_Y as well?
> } igt_rotation_t;
>
> +#define IGT_ROTATION_MASK \
> + (IGT_ROTATION_0 | IGT_ROTATION_90 | IGT_ROTATION_180 | IGT_ROTATION_270)
> +
> typedef struct {
> /*< private >*/
> igt_pipe_t *pipe;
> diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
> index 21e264a..0e2df96 100644
> --- a/tests/kms_rotation_crc.c
> +++ b/tests/kms_rotation_crc.c
> @@ -32,6 +32,7 @@ typedef struct {
> igt_display_t display;
> struct igt_fb fb;
> struct igt_fb fb_reference;
> + struct igt_fb fb_unrotated;
> struct igt_fb fb_modeset;
> struct igt_fb fb_flip;
> igt_crc_t ref_crc;
> @@ -43,8 +44,62 @@ typedef struct {
> uint32_t override_fmt;
> uint64_t override_tiling;
> bool flips;
> + int devid;
> } data_t;
>
> +typedef struct {
> + float r;
> + float g;
> + float b;
> +} rgb_color_t;
> +
> +static void set_color(rgb_color_t *color, float r, float g, float b)
> +{
> + color->r = r;
> + color->g = g;
> + color->b = b;
> +}
> +
> +static void rotate_colors(rgb_color_t *tl, rgb_color_t *tr, rgb_color_t *br,
> + rgb_color_t *bl, igt_rotation_t rotation)
> +{
> + rgb_color_t bl_tmp, br_tmp, tl_tmp, tr_tmp;
> +
> + if (rotation & IGT_REFLECT_X) {
> + bl_tmp = *bl;
> + br_tmp = *br;
> + tl_tmp = *tl;
> + tr_tmp = *tr;
> + *tl = tr_tmp;
> + *bl = br_tmp;
> + *tr = tl_tmp;
> + *br = bl_tmp;
These could use igt_swap()
> + }
> +
> + if (rotation & IGT_ROTATION_90) {
> + bl_tmp = *bl;
> + br_tmp = *br;
> + tl_tmp = *tl;
> + tr_tmp = *tr;
> + *tl = tr_tmp;
> + *bl = tl_tmp;
> + *tr = br_tmp;
> + *br = bl_tmp;
> + } else if (rotation & IGT_ROTATION_270) {
> + bl_tmp = *bl;
> + br_tmp = *br;
> + tl_tmp = *tl;
> + tr_tmp = *tr;
> + *tl = bl_tmp;
> + *bl = br_tmp;
> + *tr = tl_tmp;
> + *br = tr_tmp;
> + }
> +}
> +
> +#define RGB_COLOR(color) \
> + color.r, color.g, color.b
> +
> static void
> paint_squares(data_t *data, igt_rotation_t rotation,
> struct igt_fb *fb, float o)
> @@ -52,35 +107,26 @@ paint_squares(data_t *data, igt_rotation_t rotation,
> cairo_t *cr;
> unsigned int w = fb->width;
> unsigned int h = fb->height;
> + rgb_color_t tl, tr, bl, br;
>
> cr = igt_get_cairo_ctx(data->gfx_fd, fb);
>
> - if (rotation == IGT_ROTATION_180) {
> + set_color(&tl, o, 0, 0);
> + set_color(&tr, 0, o, 0);
> + set_color(&br, o, o, o);
> + set_color(&bl, 0, 0, o);
Maybe write the float constants as actual float constants? Would make
it much more clear that it actually takes floats instead of integers.
> +
> + rotate_colors(&tl, &tr, &br, &bl, rotation);
> +
> + if (rotation & IGT_ROTATION_180) {
> cairo_translate(cr, w, h);
> cairo_rotate(cr, M_PI);
> }
This 180 degree special case has always bothered me. Could you remove this
and just do things one way for all angles?
>
> - if (rotation == IGT_ROTATION_90) {
> - /* Paint 4 squares with width == height in Green, White,
> - Blue, Red Clockwise order to look like 270 degree rotated*/
> - igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, o, 0.0);
> - igt_paint_color(cr, w / 2, 0, w / 2, h / 2, o, o, o);
> - igt_paint_color(cr, 0, h / 2, w / 2, h / 2, o, 0.0, 0.0);
> - igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 0.0, o);
> - } else if (rotation == IGT_ROTATION_270) {
> - /* Paint 4 squares with width == height in Blue, Red,
> - Green, White Clockwise order to look like 90 degree rotated*/
> - igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, o);
> - igt_paint_color(cr, w / 2, 0, w / 2, h / 2, o, 0.0, 0.0);
> - igt_paint_color(cr, 0, h / 2, w / 2, h / 2, o, o, o);
> - igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, o, 0.0);
> - } else {
> - /* Paint with 4 squares of Red, Green, White, Blue Clockwise */
> - igt_paint_color(cr, 0, 0, w / 2, h / 2, o, 0.0, 0.0);
> - igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, o, 0.0);
> - igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, o);
> - igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, o, o, o);
> - }
> + igt_paint_color(cr, 0, 0, w / 2, h / 2, RGB_COLOR(tl));
> + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, RGB_COLOR(tr));
> + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, RGB_COLOR(bl));
> + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, RGB_COLOR(br));
>
> cairo_destroy(cr);
> }
> @@ -141,6 +187,7 @@ static void remove_fbs(data_t *data)
>
> igt_remove_fb(data->gfx_fd, &data->fb);
> igt_remove_fb(data->gfx_fd, &data->fb_reference);
> + igt_remove_fb(data->gfx_fd, &data->fb_unrotated);
>
> if (data->fb_flip.fb_id)
> igt_remove_fb(data->gfx_fd, &data->fb_flip);
> @@ -212,17 +259,12 @@ static void prepare_fbs(data_t *data, igt_output_t *output,
> * For 90/270, we will use create smaller fb so that the rotated
> * frame can fit in
> */
> - if (data->rotation == IGT_ROTATION_90 ||
> - data->rotation == IGT_ROTATION_270) {
> + if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270)) {
> tiling = data->override_tiling ?: LOCAL_I915_FORMAT_MOD_Y_TILED;
>
> igt_swap(w, h);
> }
>
> - igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb);
> -
> - igt_plane_set_rotation(plane, IGT_ROTATION_0);
> -
> /*
> * Create a reference software rotated flip framebuffer.
> */
> @@ -255,8 +297,20 @@ static void prepare_fbs(data_t *data, igt_output_t *output,
> igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
>
> /*
> + * Prepare the non-rotated reference fb.
> + */
> + igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format, tiling, &data->fb_unrotated);
> + paint_squares(data, IGT_ROTATION_0, &data->fb_unrotated, 1.0);
> + igt_plane_set_fb(plane, &data->fb_unrotated);
> + igt_plane_set_rotation(plane, IGT_ROTATION_0);
> + if (plane->type != DRM_PLANE_TYPE_CURSOR)
> + igt_plane_set_position(plane, data->pos_x, data->pos_y);
> + igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_UNIVERSAL);
> +
> + /*
> * Prepare the plane with an non-rotated fb let the hw rotate it.
> */
> + igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb);
> paint_squares(data, IGT_ROTATION_0, &data->fb, 1.0);
> igt_plane_set_fb(plane, &data->fb);
>
> @@ -322,7 +376,7 @@ static void wait_for_pageflip(int fd)
> igt_assert(drmHandleEvent(fd, &evctx) == 0);
> }
>
> -static void test_plane_rotation(data_t *data, int plane_type)
> +static void __test_plane_rotation(data_t *data, int plane_type, bool test_bad_format)
> {
> igt_display_t *display = &data->display;
> igt_output_t *output;
> @@ -345,6 +399,9 @@ static void test_plane_rotation(data_t *data, int plane_type)
> igt_plane_t *plane;
> int i;
>
> + if (IS_CHERRYVIEW(data->devid) && pipe != PIPE_B)
> + continue;
We should be able to just ask the plane which rotations it supports.
> +
> igt_output_set_pipe(output, pipe);
>
> plane = igt_output_get_plane_type(output, plane_type);
> @@ -366,14 +423,12 @@ static void test_plane_rotation(data_t *data, int plane_type)
> igt_debug("Testing case %i on pipe %s\n", i, kmstest_pipe_name(pipe));
> prepare_fbs(data, output, plane, i);
>
> - igt_display_commit2(display, commit);
> -
> igt_plane_set_rotation(plane, data->rotation);
> - if (data->rotation == IGT_ROTATION_90 || data->rotation == IGT_ROTATION_270)
> + if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
> igt_plane_set_size(plane, data->fb.height, data->fb.width);
>
> ret = igt_display_try_commit2(display, commit);
> - if (data->override_fmt || data->override_tiling) {
> + if (test_bad_format && (data->override_fmt || data->override_tiling)) {
> igt_assert_eq(ret, -EINVAL);
> continue;
> }
> @@ -410,6 +465,16 @@ static void test_plane_rotation(data_t *data, int plane_type)
> igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
> }
>
> +static inline void test_bad_plane_rotation(data_t *data, int plane_type)
> +{
> + __test_plane_rotation(data, plane_type, true);
> +}
> +
> +static inline void test_plane_rotation(data_t *data, int plane_type)
> +{
> + __test_plane_rotation(data, plane_type, false);
> +}
> +
> static void test_plane_rotation_ytiled_obj(data_t *data,
> igt_output_t *output,
> int plane_type)
> @@ -612,6 +677,8 @@ static const char *plane_test_str(unsigned plane)
> static const char *rot_test_str(igt_rotation_t rot)
> {
> switch (rot) {
> + case IGT_ROTATION_0:
> + return "0";
> case IGT_ROTATION_90:
> return "90";
> case IGT_ROTATION_180:
> @@ -623,6 +690,20 @@ static const char *rot_test_str(igt_rotation_t rot)
> }
> }
>
> +static const char *tiling_test_str(uint64_t tiling)
> +{
> + switch (tiling) {
> + case LOCAL_I915_FORMAT_MOD_X_TILED:
> + return "x-tiled";
> + case LOCAL_I915_FORMAT_MOD_Y_TILED:
> + return "y-tiled";
> + case LOCAL_I915_FORMAT_MOD_Yf_TILED:
> + return "yf-tiled";
> + default:
> + igt_assert(0);
> + }
> +}
> +
> static const char *flip_test_str(unsigned flips)
> {
> if (flips)
> @@ -653,6 +734,35 @@ igt_main
> { DRM_PLANE_TYPE_CURSOR, IGT_ROTATION_180, 0 },
> { 0, 0, 0}
> };
> +
> + struct hflip {
> + uint64_t tiling;
> + igt_rotation_t rot;
> + unsigned flips;
bool?
> + } *hflip, hflip_subtests[] = {
> + { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_0, 0 },
> + { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_180, 0 },
> + { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_0, 0 },
> + { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_90, 0 },
> + { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_180, 0 },
> + { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_270, 0 },
> + { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_0, 0},
> + { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_90, 0},
> + { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_180, 0},
> + { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_270, 0},
> + { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_0, 1 },
> + { LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_180, 1 },
> + { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_0, 1 },
> + { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_90, 1 },
> + { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_180, 1 },
> + { LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_270, 1 },
> + { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_0, 1},
> + { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_90, 1},
> + { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_180, 1},
> + { LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_270, 1},
> + { 0, 0, 0}
> + };
> +
> data_t data = {};
> int gen = 0;
>
> @@ -660,7 +770,8 @@ igt_main
>
> igt_fixture {
> data.gfx_fd = drm_open_driver_master(DRIVER_INTEL);
> - gen = intel_gen(intel_get_drm_devid(data.gfx_fd));
> + data.devid = intel_get_drm_devid(data.gfx_fd);
> + gen = intel_gen(data.devid);
>
> kmstest_set_vt_graphics_mode();
>
> @@ -697,7 +808,7 @@ igt_main
> data.pos_y = 0;
> data.rotation = IGT_ROTATION_90;
> data.override_fmt = DRM_FORMAT_RGB565;
> - test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
> + test_bad_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
> }
>
> igt_subtest_f("bad-tiling") {
> @@ -705,7 +816,7 @@ igt_main
> data.override_fmt = 0;
> data.rotation = IGT_ROTATION_90;
> data.override_tiling = LOCAL_DRM_FORMAT_MOD_NONE;
> - test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
> + test_bad_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
> }
>
> igt_subtest_f("primary-rotation-90-Y-tiled") {
> @@ -728,6 +839,20 @@ igt_main
> igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
> }
>
> + for (hflip = hflip_subtests; hflip->tiling; hflip++) {
> + igt_subtest_f("primary-h-flip-%s-%s",
I'd call it "reflect-x" or something like that since that's what the
flag is called.
> + tiling_test_str(hflip->tiling),
> + rot_test_str(hflip->rot)) {
> + igt_require(gen >= 10 ||
> + (IS_CHERRYVIEW(data.devid) && hflip->rot == IGT_ROTATION_0 &&
> + hflip->tiling == LOCAL_I915_FORMAT_MOD_X_TILED));
> + data.rotation = (IGT_REFLECT_X | hflip->rot);
> + data.override_tiling = hflip->tiling;
> + data.flips = hflip->flips;
> + test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
> + }
> + }
> +
> igt_subtest_f("exhaust-fences") {
> enum pipe pipe;
> igt_output_t *output;
> --
> 2.7.4
--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2017-09-21 10:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-21 3:50 igt/kms_rotation_crc: Add horizontal flip subtest Joseph Garvey
2017-09-21 10:57 ` Ville Syrjälä [this message]
2017-09-22 9:42 ` Petri Latvala
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170921105714.GE4914@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=joseph1.garvey@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.