[igt-dev] [PATCH i-g-t 11/11] tests/kms_big_fb: Add max hw stride lenght async flip test
Karthik B S
karthik.b.s at intel.com
Thu Jun 10 06:14:14 UTC 2021
On 6/9/2021 5:47 PM, venkata.sai.patnana at intel.com wrote:
> From: Juha-Pekka Heikkilä <juha-pekka.heikkila at intel.com>
>
> test async flip with fbs which are using maximum hw supported stride
> lenghts. Do crc test flipping between fbs which are having same content
> and then async flip fbs with different content.
>
> Cc: Karthik B S <karthik.b.s at intel.com>
> Signed-off-by: Juha-Pekka Heikkilä <juha-pekka.heikkila at intel.com>
Reviewed-by: Karthik B S <karthik.b.s at intel.com>
> ---
> tests/kms_big_fb.c | 147 ++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 140 insertions(+), 7 deletions(-)
>
> diff --git a/tests/kms_big_fb.c b/tests/kms_big_fb.c
> index 65565127fd..89ea0f23e2 100644
> --- a/tests/kms_big_fb.c
> +++ b/tests/kms_big_fb.c
> @@ -39,7 +39,7 @@ typedef struct {
> igt_output_t *output;
> igt_plane_t *plane;
> igt_pipe_crc_t *pipe_crc;
> - struct igt_fb small_fb, big_fb;
> + struct igt_fb small_fb, big_fb, big_fb_flip[2];
> uint32_t format;
> uint64_t modifier;
> int width, height;
> @@ -51,10 +51,13 @@ typedef struct {
> struct buf_ops *bops;
> struct intel_bb *ibb;
> bool max_hw_stride_test;
> + bool async_flip_test;
> int hw_stride;
> int max_hw_fb_width;
> + double planeclearrgb[3];
> uint32_t format_override;
> uint32_t stride_override;
> + uint32_t async_flip_support;
> } data_t;
>
> static struct intel_buf *init_buf(data_t *data,
> @@ -113,7 +116,10 @@ static void setup_fb(data_t *data, struct igt_fb *newfb, uint32_t width,
> }
>
> cr = igt_get_cairo_ctx(data->drm_fd, newfb);
> - igt_paint_color(cr, 0, 0, newfb->width, newfb->height, 0, 0, 0);
> + igt_paint_color(cr, 0, 0, newfb->width, newfb->height,
> + data->planeclearrgb[0],
> + data->planeclearrgb[1],
> + data->planeclearrgb[2]);
> igt_put_cairo_ctx(cr);
>
> igt_assert(drmIoctl(data->drm_fd, LOCAL_DRM_IOCTL_MODE_ADDFB2, &f) == 0);
> @@ -243,7 +249,7 @@ static void prep_fb(data_t *data)
> if (data->big_fb.fb_id)
> return;
>
> - if (data->hw_stride == 0) {
> + if (!data->max_hw_stride_test) {
> igt_create_fb(data->drm_fd,
> data->big_fb_width, data->big_fb_height,
> data->format, data->modifier,
> @@ -252,7 +258,7 @@ static void prep_fb(data_t *data)
> setup_fb(data, &data->big_fb, data->big_fb_width,
> data->big_fb_height, data->format, data->modifier,
> data->hw_stride);
> - igt_info("using stride length %d\n", data->hw_stride);
> + igt_debug("using stride length %d\n", data->hw_stride);
> }
>
> generate_pattern(data, &data->big_fb, 640, 480);
> @@ -474,11 +480,107 @@ static bool test_pipe(data_t *data)
> return ret;
> }
>
> +static bool
> +max_hw_stride_async_flip_test(data_t *data)
> +{
> + uint32_t ret, startframe;
> + const uint32_t w = data->output->config.default_mode.hdisplay,
> + h = data->output->config.default_mode.vdisplay;
> + igt_plane_t *primary;
> + igt_crc_t compare_crc, async_crc;
> +
> + igt_require(data->display.is_atomic);
> + igt_output_set_pipe(data->output, data->pipe);
> +
> + primary = igt_output_get_plane_type(data->output, DRM_PLANE_TYPE_PRIMARY);
> +
> + if (igt_plane_has_prop(primary, IGT_PLANE_ROTATION))
> + igt_plane_set_rotation(primary, data->rotation);
> +
> + igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +
> + setup_fb(data, &data->big_fb, data->big_fb_width, data->big_fb_height,
> + data->format, data->modifier, data->hw_stride);
> + generate_pattern(data, &data->big_fb, 640, 480);
> +
> + data->planeclearrgb[1] = 1.0;
> +
> + setup_fb(data, &data->big_fb_flip[0], data->big_fb_width,
> + data->big_fb_height, data->format, data->modifier,
> + data->hw_stride);
> +
> + data->planeclearrgb[1] = 0.0;
> +
> + setup_fb(data, &data->big_fb_flip[1], data->big_fb_width,
> + data->big_fb_height, data->format, data->modifier,
> + data->hw_stride);
> + generate_pattern(data, &data->big_fb_flip[1], 640, 480);
> +
> + data->pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe,
> + INTEL_PIPE_CRC_SOURCE_AUTO);
> + igt_pipe_crc_start(data->pipe_crc);
> +
> + igt_set_timeout(5, "Async pageflipping loop got stuck!\n");
> + for (int i = 0; i < 2; i++) {
> + igt_plane_set_fb(primary, &data->big_fb);
> + igt_fb_set_size(&data->big_fb, primary, w, h);
> + igt_plane_set_size(primary, w, h);
> + igt_display_commit_atomic(&data->display,
> + DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> +
> + igt_wait_for_vblank(data->drm_fd, data->display.pipes[primary->pipe->pipe].crtc_offset);
> + startframe = kmstest_get_vblank(data->drm_fd, data->pipe, 0) + 1;
> +
> + for (int j = 0; j < 2; j++) {
> + do {
> + ret = drmModePageFlip(data->drm_fd, data->output->config.crtc->crtc_id,
> + data->big_fb_flip[i].fb_id,
> + DRM_MODE_PAGE_FLIP_ASYNC, NULL);
> + } while (ret == -EBUSY);
> + igt_assert(ret == 0);
> +
> + do {
> + ret = drmModePageFlip(data->drm_fd, data->output->config.crtc->crtc_id,
> + data->big_fb.fb_id,
> + DRM_MODE_PAGE_FLIP_ASYNC, NULL);
> + } while (ret == -EBUSY);
> + igt_assert(ret == 0);
> + }
> +
> + igt_pipe_crc_get_for_frame(data->drm_fd, data->pipe_crc,
> + startframe, &compare_crc);
> + igt_pipe_crc_get_for_frame(data->drm_fd, data->pipe_crc,
> + startframe + 1, &async_crc);
> +
> + igt_assert_f(kmstest_get_vblank(data->drm_fd, data->pipe, 0) -
> + startframe == 1, "lost frames\n");
> +
> + igt_assert_f(igt_check_crc_equal(&compare_crc, &async_crc)^(i^1),
> + "CRC failure with async flip, crc %s match for checked round\n",
> + i?"should":"shouldn't");
> + }
> + igt_reset_timeout();
> +
> + igt_pipe_crc_free(data->pipe_crc);
> + igt_output_set_pipe(data->output, PIPE_NONE);
> + igt_remove_fb(data->drm_fd, &data->big_fb);
> + igt_remove_fb(data->drm_fd, &data->big_fb_flip[0]);
> + igt_remove_fb(data->drm_fd, &data->big_fb_flip[1]);
> + return true;
> +}
> +
> static void test_scanout(data_t *data)
> {
> + igt_output_t *output;
> +
> if (data->max_hw_stride_test) {
> data->big_fb_width = data->max_hw_fb_width;
> - data->big_fb_height = data->max_hw_fb_width;
> + data->big_fb_height = 0;
> +
> + for_each_connected_output(&data->display, output) {
> + if (data->big_fb_height < output->config.default_mode.vdisplay * 2)
> + data->big_fb_height = output->config.default_mode.vdisplay * 2;
> + }
> } else {
> data->big_fb_width = data->max_fb_width;
> data->big_fb_height = data->max_fb_height;
> @@ -488,8 +590,13 @@ static void test_scanout(data_t *data)
> data->format, data->modifier);
>
> for_each_pipe_with_valid_output(&data->display, data->pipe, data->output) {
> - if (test_pipe(data))
> - return;
> + if (data->async_flip_test) {
> + if (max_hw_stride_async_flip_test(data))
> + return;
> + } else {
> + if (test_pipe(data))
> + return;
> + }
> break;
> }
>
> @@ -699,6 +806,7 @@ igt_main
> {
> igt_fixture {
> drmModeResPtr res;
> + struct drm_get_cap cap = { .capability = DRM_CAP_ASYNC_PAGE_FLIP };
>
> data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
>
> @@ -743,7 +851,15 @@ igt_main
> data.bops = buf_ops_create(data.drm_fd);
> data.ibb = intel_bb_create(data.drm_fd, 4096);
>
> + data.planeclearrgb[0] = 0.0;
> + data.planeclearrgb[1] = 0.0;
> + data.planeclearrgb[2] = 0.0;
> +
> data.max_hw_stride_test = false;
> + data.async_flip_test = false;
> +
> + igt_ioctl(data.drm_fd, DRM_IOCTL_GET_CAP, &cap);
> + data.async_flip_support = cap.value;
> }
>
> /*
> @@ -861,6 +977,23 @@ igt_main
> igt_require(igt_display_has_format_mod(&data.display, data.format, data.modifier));
> test_scanout(&data);
> }
> +
> + // async flip doesn't support linear fbs.
> + if (modifiers[i].modifier == DRM_FORMAT_MOD_LINEAR)
> + continue;
> +
> + data.async_flip_test = true;
> + igt_describe("test async flip on maximum hardware supported stride length for given bpp and modifiers.");
> + igt_subtest_f("%s-max-hw-stride-%dbpp-rotate-%d%s-async-flip", modifiers[i].name,
> + formats[j].bpp, rotations[k].angle, fliptab[l].flipname) {
> + igt_require(data.format == DRM_FORMAT_C8 ||
> + igt_fb_supported_format(data.format));
> + igt_require(igt_display_has_format_mod(&data.display, data.format, data.modifier));
> + igt_require_f(data.async_flip_support, "Async Flip is not supported\n");
> + data.max_hw_fb_width = min(data.hw_stride / (formats[j].bpp >> 3), data.max_fb_width);
> + test_scanout(&data);
> + }
> + data.async_flip_test = false;
> }
>
> igt_fixture
More information about the igt-dev
mailing list