[igt-dev] [PATCH v2 4/4] tests/amdgpu/amd_psr: add PSR-SU MPO subtest case

Aurabindo Pillai aurabindo.pillai at amd.com
Fri Mar 11 21:27:47 UTC 2022



On 2022-03-11 14:44, David Zhang wrote:
> [why]
> We need a test case to imitate the multiplane overlay (MPO) video
> playback use case and check PSR-SU enablement during test run.
> 
> [how]
> The test run only works for PSR-SU capable sink device and skip for
> any non-eDP or non-PSR-SU connector or kernel driver not supporting
> PSR-SU feature.
> 
> To emulate the video playback and MPO scenario, we use overlay plane
> w/ size of addressable and primary plane w/ size of quater of overlay
> acting as video playback region.
> 
> Create couple of framebuffers w/ size of primary plane and with
> the pattern of vertical color strip on different position on the
> FB. During test run, we flip the primary framebuffer and expect the
> visual effect of moving strip within the region of primary plane
> acting as video playback. The primary plane during test run is not
> moving position or resizing.
> 
> changes in v2
> ----------------
> * move #define statement to top of the source file.
> 
> Cc: Rodrigo Siqueira <rodrigo.siqueira at amd.com>
> Cc: Harry Wentland <harry.wentland at amd.com>
> Cc: Leo Li <sunpeng.li at amd.com>
> Cc: Jay Pillai <aurabindo.pillai at amd.com>
> Cc: Wayne Lin <wayne.lin at amd.com>
> 
> Signed-off-by: David Zhang <dingchen.zhang at amd.com>
> ---
>   lib/igt_amd.h          |  25 ++++++++
>   tests/amdgpu/amd_psr.c | 138 +++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 163 insertions(+)
> 
> diff --git a/lib/igt_amd.h b/lib/igt_amd.h
> index f87c1991..e4e12ce5 100644
> --- a/lib/igt_amd.h
> +++ b/lib/igt_amd.h
> @@ -90,6 +90,31 @@ enum dc_link_training_type {
>   	LINK_TRAINING_NO_PATTERN
>   };
>   
> +/*
> + * enumeration of PSR STATE below should be aligned to the upstreamed
> + * amdgpu kernel driver 'enum dc_psr_state' in dc_type.h
> + */
> +enum amdgpu_psr_state {
> +	PSR_STATE0 = 0x0,
> +	PSR_STATE1,
> +	PSR_STATE1a,
> +	PSR_STATE2,
> +	PSR_STATE2a,
> +	PSR_STATE2b,
> +	PSR_STATE3,
> +	PSR_STATE3Init,
> +	PSR_STATE4,
> +	PSR_STATE4a,
> +	PSR_STATE4b,
> +	PSR_STATE4c,
> +	PSR_STATE4d,
> +	PSR_STATE5,
> +	PSR_STATE5a,
> +	PSR_STATE5b,
> +	PSR_STATE5c,
> +	PSR_STATE_INVALID = 0xFF
> +};
> +
>   uint32_t igt_amd_create_bo(int fd, uint64_t size);
>   void *igt_amd_mmap_bo(int fd, uint32_t handle, uint64_t size, int prot);
>   unsigned int igt_amd_compute_offset(unsigned int* swizzle_pattern,
> diff --git a/tests/amdgpu/amd_psr.c b/tests/amdgpu/amd_psr.c
> index 88e824c3..d80820c8 100644
> --- a/tests/amdgpu/amd_psr.c
> +++ b/tests/amdgpu/amd_psr.c
> @@ -32,6 +32,7 @@
>   /* hardware requirements:
>    * 1. eDP panel that supports PSR (multiple panel can be connected at the same time)
>    * 2. Optional DP display for testing a regression condition (setting crtc to null)
> + * 3. eDP panel that supports PSR-SU
>    */
>   IGT_TEST_DESCRIPTION("Basic test for enabling Panel Self Refresh for eDP displays");
>   
> @@ -39,22 +40,39 @@ IGT_TEST_DESCRIPTION("Basic test for enabling Panel Self Refresh for eDP display
>   #define N_FLIPS 6
>   /* DMCUB takes some time to actually enable PSR. Worst case delay is 4 seconds */
>   #define PSR_SETTLE_DELAY 4
> +/* # of framebuffers for PSR-SU MPO test case to emulate video playback */
> +#ifndef N_MPO_TEST_RECT_FB
> +#define N_MPO_TEST_RECT_FB 20
> +#endif
>   
>   /* Common test data. */
>   typedef struct data {
>           igt_display_t display;
>           igt_plane_t *primary;
>           igt_plane_t *cursor;
> +	igt_plane_t *overlay;

Looks like spaces were used here originally, and this change uses tabs. 
For consistency, please use spaces here or change reformat the whole 
definition to use tabs. I think all the following indentation issues are 
for same reason:

>           igt_output_t *output;
>           igt_pipe_t *pipe;
>           igt_pipe_crc_t *pipe_crc;
>           drmModeModeInfo *mode;
>           enum pipe pipe_id;
>           int fd;
> +	int debugfs_fd;

Indentation
>           int w;
>           int h;
>   } data_t;
>   
> +static void draw_color_alpha(igt_fb_t *fb, int x, int y, int w, int h,
> +		             double r, double g, double b, double a)
> +{
> +	cairo_t *cr = igt_get_cairo_ctx(fb->fd, fb);
> +
> +	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
> +	igt_paint_color_alpha(cr, x, y, w, h, r, g, b, a);
> +
> +	igt_put_cairo_ctx(cr);
> +}
> +
>   /* Common test setup. */
>   static void test_init(data_t *data)
>   {
> @@ -68,9 +86,11 @@ static void test_init(data_t *data)
>   
>           data->output = igt_get_single_output_for_pipe(display, data->pipe_id);
>           igt_require(data->output);
> +	igt_info("output %s\n", data->output->name);

Indentation
>   
>           data->mode = igt_output_get_mode(data->output);
>           igt_assert(data->mode);
> +	kmstest_dump_mode(data->mode);

Indentation
>   
>           data->primary =
>                   igt_pipe_get_plane_type(data->pipe, DRM_PLANE_TYPE_PRIMARY);
> @@ -78,6 +98,9 @@ static void test_init(data_t *data)
>           data->cursor =
>                   igt_pipe_get_plane_type(data->pipe, DRM_PLANE_TYPE_CURSOR);
>   
> +	data->overlay =

Indentation
> +		igt_pipe_get_plane_type(data->pipe, DRM_PLANE_TYPE_OVERLAY);
> +
>           data->pipe_crc = igt_pipe_crc_new(data->fd, data->pipe_id, "auto");
>   
>           igt_output_set_pipe(data->output, data->pipe_id);
> @@ -181,6 +204,114 @@ static void run_check_psr(data_t *data, bool test_null_crtc) {
>   	test_fini(data);
>   }
>   
> +static void run_check_psr_su_mpo(data_t *data)
> +{
> +	int edp_idx = check_conn_type(data, DRM_MODE_CONNECTOR_eDP);
> +	bool sink_support_psrsu = false;
> +	bool drv_suport_psrsu = false;
> +	igt_fb_t ov_fb;		// fb for overlay
> +	igt_fb_t rect_fb[N_MPO_TEST_RECT_FB]; 	// rectangle fbs for primary, emulate as video playback region
> +	igt_fb_t ref_fb;	// reference fb
> +	igt_fb_t *flip_fb;
> +	int ret;
> +	const int run_sec = 5;
> +	enum amdgpu_psr_state psr_state = PSR_STATE0;
> +	int frame_rate = 0;
> +
> +	/* skip the test run if no eDP sink detected */
> +	igt_skip_on_f(edp_idx == -1, "no eDP connector found\n");
> +
> +	/* init */
> +	test_init(data);
> +	frame_rate = data->mode->vrefresh;
> +
> +	/* run the test i.i.f. eDP panel supports and kernel driver both support PSR-SU  */
> +	igt_skip_on(!igt_amd_output_has_psr_cap(data->fd, data->output->name));
> +	igt_skip_on(!igt_amd_output_has_psr_state(data->fd, data->output->name));
> +	sink_support_psrsu = igt_amd_psr_support_sink(data->fd, data->output->name, PSR_MODE_2);
> +	igt_skip_on_f(!sink_support_psrsu, "output %s not support PSR-SU\n", data->output->name);
> +	drv_suport_psrsu = igt_amd_psr_support_drv(data->fd, data->output->name, PSR_MODE_2);
> +	igt_skip_on_f(!drv_suport_psrsu, "kernel driver not support PSR-SU\n");
> +
> +	/* reference background pattern in grey */
> +	igt_create_color_fb(data->fd, data->w, data->h, DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
> +			    .5, .5, .5, &ref_fb);
> +	igt_plane_set_fb(data->primary, &ref_fb);
> +	igt_output_set_pipe(data->output, data->pipe_id);
> +	igt_display_commit_atomic(&data->display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> +
> +	/*
> +	 * overlay and primary fbs creation
> +	 * for MPO vpb use case, the vpb is always in the primary plane as an underlay,
> +	 * while the control panel/tool bar such icons/items are all in the overlay plane,
> +	 * and alpha for vpb region is adjusted to control the transparency.
> +	 * thus the overlay fb be initialized w/ ARGB pixel format to support blending
> +	 */
> +	igt_create_color_fb(data->fd, data->w, data->h, DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_LINEAR,
> +			    1.0, 1.0, 1.0, &ov_fb);
> +	for (int i = 0; i < N_MPO_TEST_RECT_FB; ++i) {
> +		cairo_t *cr;
> +		int strip_w = data->w / (2 * N_MPO_TEST_RECT_FB);
> +
> +		igt_create_fb(data->fd, data->w / 2, data->h / 2, DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
> +			      &rect_fb[i]);
> +		cr = igt_get_cairo_ctx(data->fd, &rect_fb[i]);
> +		igt_assert_f(cr, "Failed to get cairo context\n");
> +		/* background in black */
> +		igt_paint_color(cr, 0, 0, data->w, data->h, .0, .0, .0);
> +		/* foreground (megenta strip) */
> +		igt_paint_color(cr, i * strip_w, 0, strip_w, data->h, 1.0, .0, 1.0);
> +
> +		igt_put_cairo_ctx(cr);
> +	}
> +
> +	/* tie fbs to planes and set position/size/blending */
> +	igt_plane_set_fb(data->overlay, &ov_fb);
> +	igt_plane_set_fb(data->primary, &rect_fb[0]);
> +	igt_plane_set_position(data->primary, 0, 0);
> +	igt_plane_set_size(data->primary, data->w / 2, data->h / 2);
> +
> +	/* adjust alpha for vpb (primary plane) region in overlay */
> +	draw_color_alpha(&ov_fb, 0, 0, data->w / 2, data->h / 2, .5, .5, .5, .3);
> +
> +	igt_output_set_pipe(data->output, data->pipe_id);
> +	igt_display_commit_atomic(&data->display, 0, NULL);
> +
> +	/* multiplane overlay to emulate video playback use case */
> +	igt_info("\n start flipping ...\n");
> +
> +	for (int i = 0; i < run_sec * frame_rate; ++i) {
> +		igt_info(" About to commit a primary plane (FB %d), loop %d \n", i % N_MPO_TEST_RECT_FB, i);
> +		flip_fb = &rect_fb[i % N_MPO_TEST_RECT_FB];
> +
> +		igt_plane_set_fb(data->primary, flip_fb);
> +		igt_output_set_pipe(data->output, data->pipe_id);
> +
> +		ret = drmModePageFlip(data->fd, data->output->config.crtc->crtc_id,
> +				      flip_fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, NULL);
> +		igt_require(ret == 0);
> +		kmstest_wait_for_pageflip(data->fd);
> +
> +		/* check PSR state */
> +		if (i > PSR_SETTLE_DELAY * frame_rate) {
> +			psr_state = igt_amd_read_psr_state(data->fd, data->output->name);
> +			igt_fail_on_f(psr_state == PSR_STATE0,
> +				"PSR was not enabled for connector %s\n", data->output->name);
> +			igt_fail_on_f(psr_state == PSR_STATE_INVALID,
> +				"PSR is invalid for connector %s\n", data->output->name);
> +			igt_fail_on_f(psr_state != PSR_STATE3,
> +				"PSR state is expected to be STATE_3 for connector %s\n", data->output->name);
> +		}
> +	}
> +
> +	/* fini */
> +	igt_remove_fb(data->fd, &ref_fb);
> +	igt_remove_fb(data->fd, &ov_fb);
> +	for (int i = 0; i < N_MPO_TEST_RECT_FB; ++i) igt_remove_fb(data->fd, &rect_fb[i]);

Nitpick: newline after for loop for readabiltiy

> +	test_fini(data);
> +	close(data->fd);
> +}
> +
>   igt_main
>   {
>   	data_t data;
> @@ -191,6 +322,8 @@ igt_main
>   	igt_fixture
>   	{
>   		data.fd = drm_open_driver_master(DRIVER_AMDGPU);
> +		if (data.fd == -1) igt_skip("Not an amdgpu driver.\n");
> +		data.debugfs_fd = igt_debugfs_dir(data.fd);
>   
>   		kmstest_set_vt_graphics_mode();
>   
> @@ -205,8 +338,13 @@ igt_main
>   	igt_describe("Test whether setting CRTC to null triggers any warning with PSR enabled");
>   	igt_subtest("psr_enable_null_crtc") run_check_psr(&data, true);
>   
> +	igt_describe("Test to validate PSR SU enablement with Visual Confirm "
> +		     "and to imitate Multiplane Overlay video playback scenario");
> +	igt_subtest("psr_su_mpo") run_check_psr_su_mpo(&data);
> +
>   	igt_fixture
>   	{
> +		close(data.debugfs_fd);
>   		igt_display_fini(&data.display);
>   	}
>   }


More information about the igt-dev mailing list