[igt-dev] [PATCH i-g-t v3 3/3] tests/kms_atomic: Add a new test case for FB_DAMAGE_CLIPS plane property
Hogander, Jouni
jouni.hogander at intel.com
Tue Nov 23 11:33:02 UTC 2021
On Wed, 2021-11-10 at 01:25 +0530, Jeevan B wrote:
> From: Deepak Rawat <drawat at vmware.com>
>
> Some simple test cases to use FB_DAMAGE_CLIPS plane property.
Maybe you could describe a bit more what are the testcase you are
adding.
>
> Signed-off-by: Deepak Rawat <drawat at vmware.com>
> Signed-off-by: Jeevan B <jeevan.b at intel.com>
> ---
> tests/kms_atomic.c | 232
> +++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 232 insertions(+)
>
> diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
> index 1657624e..4b7b6d38 100644
> --- a/tests/kms_atomic.c
> +++ b/tests/kms_atomic.c
> @@ -62,6 +62,25 @@ enum kms_atomic_check_relax {
> PLANE_RELAX_FB = (1 << 1)
> };
>
> +/* signed32 drm_mode_rect declared here for use with drm damage for
> page-flip */
> +struct damage_rect {
> + int x1;
> + int y1;
> + int x2;
> + int y2;
> +};
Consider using igt-gpu-tools/include/drm-uapi/drm_mode.h:drm_mode_rect.
> +
> +static inline int damage_rect_width(struct damage_rect *r)
> +{
> + return r->x2 - r->x1;
> +}
> +
> +static inline int damage_rect_height(struct damage_rect *r)
> +{
> + return r->y2 - r->y1;
> +}
> +
> +
> static bool plane_filter(enum igt_atomic_plane_properties prop)
> {
> if ((1 << prop) & IGT_PLANE_COORD_CHANGED_MASK)
> @@ -1060,6 +1079,210 @@ static void atomic_invalid_params(igt_pipe_t
> *pipe,
> do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
> }
>
> +static void atomic_plane_damage(igt_pipe_t *pipe, igt_plane_t
> *plane, struct igt_fb *fb)
> +{
> + struct damage_rect *damage;
> + struct igt_fb fb_1, fb_2;
> + cairo_t *cr_1, *cr_2;
> +
> + damage = malloc(sizeof(*damage) * 2);
> + igt_assert(damage);
To my opinion it's better to have "drm_mode_rect damage_rect[2]" rather
than using malloc here. Anyways I think "free" is not done if there is
assertion later for some reason.
> +
> + /* Color fb with white rect at center */
> + igt_create_color_fb(pipe->display->drm_fd, fb->width, fb-
> >height,
> + fb->drm_format, I915_TILING_NONE, 0.2, 0.2,
> 0.2,
> + &fb_1);
> + cr_1 = igt_get_cairo_ctx(pipe->display->drm_fd, &fb_1);
> + igt_paint_color(cr_1, fb->width/4, fb->height/4, fb->width/2,
> + fb->height/2, 1.0, 1.0, 1.0);
> + igt_put_cairo_ctx(cr_1);
> +
> + /*
> + * Flip the primary plane to new color fb using atomic API and
> check the
> + * state.
> + */
> + igt_plane_set_fb(plane, &fb_1);
> + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
> +
From here ->
> + /*
> + * Change the color of top left clip from center and issue
> plane update
> + * with damage and verify the state.
> + */
> + damage[0].x1 = 0;
> + damage[0].y1 = 0;
> + damage[0].x2 = fb->width/2;
> + damage[0].y2 = fb->height/2;
> +
> + cr_1 = igt_get_cairo_ctx(pipe->display->drm_fd, &fb_1);
> + igt_paint_color(cr_1, damage[0].x1, damage[0].y1,
> + damage_rect_width(&damage[0]),
> + damage_rect_height(&damage[0]), 1.0, 0, 0);
> + igt_put_cairo_ctx(cr_1);
> +
> + igt_plane_set_fb(plane, &fb_1);
> + igt_plane_replace_prop_blob(plane, IGT_PLANE_FB_DAMAGE_CLIPS,
> damage,
> + sizeof(*damage));
> + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
<- To here: consider putting the code into a function(s). You are
repeating this code 7 times.
> +
> + /*
> + * Change the color of top left and bottom right clip from
> center and
> + * issue plane update with damage and verify the state.
> + */
> + igt_create_color_fb(pipe->display->drm_fd, fb->width, fb-
> >height,
> + fb->drm_format, I915_TILING_NONE, 0.2, 0.2,
> 0.2,
> + &fb_2);
> +
> + damage[0].x1 = fb->width/2;
> + damage[0].y1 = 0;
> + damage[0].x2 = fb->width;
> + damage[0].y2 = fb->height/2;
> +
> + cr_2 = igt_get_cairo_ctx(pipe->display->drm_fd, &fb_2);
> + cr_1 = igt_get_cairo_ctx(pipe->display->drm_fd, &fb_1);
> + cairo_set_source_surface(cr_2, fb_1.cairo_surface, 0, 0);
> + cairo_paint(cr_2);
> + igt_paint_color(cr_2, damage[0].x1, damage[0].y1,
> + damage_rect_width(&damage[0]),
> + damage_rect_height(&damage[0]), 0, 1.0, 0);
> + igt_put_cairo_ctx(cr_1);
> + igt_put_cairo_ctx(cr_2);
> + igt_plane_set_fb(plane, &fb_2);
> + igt_plane_replace_prop_blob(plane, IGT_PLANE_FB_DAMAGE_CLIPS,
> damage,
> + sizeof(*damage));
> + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
> +
> + /*
> + * Issue plane update with damage with a clip outside of plane
> src.
> + * NOTE: This will result in no update on plane as damage is
> outside, so
> + * will see no change on the screen.
> + */
> + /* Reszie fb_1 to be bigger than plane */
> + igt_remove_fb(pipe->display->drm_fd, &fb_1);
> + igt_create_color_fb(pipe->display->drm_fd, fb->width * 2, fb-
> >height,
> + fb->drm_format, I915_TILING_NONE, 0.2, 0.2,
> 0.2,
> + &fb_1);
> +
> + damage[0].x1 = fb->width;
> + damage[0].y1 = 0;
> + damage[0].x2 = fb->width + fb->width/2;
> + damage[0].y2 = fb->height/2;
> +
> + cr_1 = igt_get_cairo_ctx(pipe->display->drm_fd, &fb_1);
> + cr_2 = igt_get_cairo_ctx(pipe->display->drm_fd, &fb_2);
> + cairo_set_source_surface(cr_1, fb_2.cairo_surface, 0, 0);
> + cairo_paint(cr_1);
> + igt_paint_color(cr_1, damage[0].x1, damage[0].y1,
> + damage_rect_width(&damage[0]),
> + damage_rect_height(&damage[0]), 0, 1.0, 0);
> + igt_put_cairo_ctx(cr_2);
> + igt_put_cairo_ctx(cr_1);
> + igt_plane_set_fb(plane, &fb_1);
> + igt_plane_set_size(plane, fb->width, fb->height);
> + igt_fb_set_position(&fb_1, plane, 0, 0);
> + igt_fb_set_size(&fb_1, plane, fb->width, fb->height);
> + igt_plane_replace_prop_blob(plane, IGT_PLANE_FB_DAMAGE_CLIPS,
> damage,
> + sizeof(*damage));
> + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
> +
> + /*
> + * Issue a plane update with damage with a clip that overlap
> with plane
> + * src (Top right from center extending outside src in below
> case).
> + * NOTE: Here drm core should take care of intersecting the
> clip to
> + * plane src.
> + */
> + damage[0].x1 = fb->width/2;
> + damage[0].y1 = 0;
> + damage[0].x2 = fb->width/2 + fb->width;
> + damage[0].y2 = fb->height/2;
> +
> + cr_1 = igt_get_cairo_ctx(pipe->display->drm_fd, &fb_1);
> + igt_paint_color(cr_1, damage[0].x1, damage[0].y1,
> + damage_rect_width(&damage[0]),
> + damage_rect_height(&damage[0]), 1.0, 1.0, 0);
> + igt_put_cairo_ctx(cr_1);
> + igt_plane_set_fb(plane, &fb_1);
> + igt_plane_set_size(plane, fb->width, fb->height);
> + igt_fb_set_position(&fb_1, plane, 0, 0);
> + igt_fb_set_size(&fb_1, plane, fb->width, fb->height);
> + igt_plane_replace_prop_blob(plane, IGT_PLANE_FB_DAMAGE_CLIPS,
> damage,
> + sizeof(*damage));
> + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
> +
> + /*
> + * Issue a plane update with damage with two clips one inside
> plane src
> + * and one outside
> + * NOTE: This will result in plane update with clip inside
> plane src.
> + */
> + damage[0].x1 = 0;
> + damage[0].y1 = fb->height/2;
> + damage[0].x2 = fb->width/2;
> + damage[0].y2 = fb->height;
> +
> + damage[1].x1 = fb->width + fb->width/2;
> + damage[1].y1 = fb->height/2;
> + damage[1].x2 = fb->width * 2;
> + damage[1].y2 = fb->height;
> +
> + cr_1 = igt_get_cairo_ctx(pipe->display->drm_fd, &fb_1);
> + igt_paint_color(cr_1, damage[0].x1, damage[0].y1,
> + damage_rect_width(&damage[0]),
> + damage_rect_height(&damage[0]), 0, 1.0, 1.0);
> + igt_paint_color(cr_1, damage[1].x1, damage[1].y1,
> + damage_rect_width(&damage[1]),
> + damage_rect_height(&damage[1]), 0, 1.0, 0);
> + igt_put_cairo_ctx(cr_1);
> + igt_plane_set_fb(plane, &fb_1);
> + igt_plane_set_size(plane, fb->width, fb->height);
> + igt_fb_set_position(&fb_1, plane, 0, 0);
> + igt_fb_set_size(&fb_1, plane, fb->width, fb->height);
> + igt_plane_replace_prop_blob(plane, IGT_PLANE_FB_DAMAGE_CLIPS,
> damage,
> + sizeof(*damage) * 2);
> + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
> +
> + /*
> + * Issue a plane update with overlapping damage clips. White
> rect in
> + * center overlap partially with top left red rect.
> + * NOTE: Drm core does not error for overlapping damage clips
> so if any
> + * driver does not support overlapping should have their own
> + * validations.
> + */
> + damage[0].x1 = 0;
> + damage[0].y1 = 0;
> + damage[0].x2 = fb->width/2;
> + damage[0].y2 = fb->height/2;
> +
> + damage[1].x1 = fb->width/4;
> + damage[1].y1 = fb->height/4;
> + damage[1].x2 = fb->width/4 + fb->width/2;
> + damage[1].y2 = fb->height/4 + fb->height/2;
> +
> + cr_1 = igt_get_cairo_ctx(pipe->display->drm_fd,
> &fb_drm_mode_rect1);
> + igt_paint_color(cr_1, damage[0].x1, damage[0].y1,
> + damage_rect_width(&damage[0]),
> + damage_rect_height(&damage[0]), 1.0, 0, 0);
> + igt_paint_color(cr_1, damage[1].x1, damage[1].y1,
> + damage_rect_width(&damage[1]),
> + damage_rect_height(&damage[1]), 1.0, 1.0, 1.0);
> + igt_put_cairo_ctx(cr_1);
> + igt_plane_set_fb(plane, &fb_1);
> + igt_plane_set_size(plane, fb->width, fb->height);
> + igt_fb_set_position(&fb_1, plane, 0, 0);
> + igt_fb_set_size(&fb_1, plane, fb->width, fb->height);
> + igt_plane_replace_prop_blob(plane, IGT_PLANE_FB_DAMAGE_CLIPS,
> damage,
> + sizeof(*damage) * 2);
> + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
> +
> + /* Restore the primary plane */
> + igt_plane_set_fb(plane, fb);
> + plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
> +
> + /* Remove the fb created for this test */
> + igt_remove_fb(pipe->display->drm_fd, &fb_1);
> + igt_remove_fb(pipe->display->drm_fd, &fb_2);
> +
> + free(damage);
> +}
> +
> static void atomic_setup(igt_display_t *display, enum pipe pipe,
> igt_output_t *output, igt_plane_t *primary, struct igt_fb *fb)
> {
> igt_output_set_pipe(output, pipe);
> @@ -1219,6 +1442,15 @@ igt_main
> atomic_invalid_params(pipe_obj, primary, output, &fb);
> }
>
> + igt_describe("Simple test cases to use FB_DAMAGE_CLIPS plane
> property");
> + igt_subtest("atomic_plane_damage") {
> + igt_require(igt_plane_has_prop(primary,
> IGT_PLANE_FB_DAMAGE_CLIPS));
> +
> + atomic_setup(&display, pipe, output, primary, &fb);
> +
> + atomic_plane_damage(pipe_obj, primary, &fb);
> + }
> +
> igt_fixture {
> atomic_clear(&display, pipe, primary, output);
> igt_remove_fb(display.drm_fd, &fb);
BR,
Jouni Högander
More information about the igt-dev
mailing list