[igt-dev] [PATCH 3/4] tests/amdgpu/amd_psr: use double framebuffers to emulate MPO case

Leo sunpeng.li at amd.com
Mon May 9 19:10:20 UTC 2022



On 2022-05-05 17:32, David Zhang wrote:
> [why]
> Current implementation to emulate the MPO video playback is via
> creating 20 framebuffers (FB) and each FB has a colorful strip
> pattern in a different position. From usrmode's view, in general
> it would not create so many FBs for primary plane. Instead, it
> only creates double or tripple buffers.
> 
> [how]
> - drop the 20 framebuffers in current implementation
> - use the double primary plane framebuffers defined in data struct
>   and update the strip pattern alternatively on the double FBs and
>   do page flip for each iteration
> 
> 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>

Reviewed-by: Leo Li <sunpeng.li at amd.com>

> ---
>  tests/amdgpu/amd_psr.c | 76 +++++++++++++++++++++++++++---------------
>  1 file changed, 49 insertions(+), 27 deletions(-)
> 
> diff --git a/tests/amdgpu/amd_psr.c b/tests/amdgpu/amd_psr.c
> index 29982605..81ebebd3 100644
> --- a/tests/amdgpu/amd_psr.c
> +++ b/tests/amdgpu/amd_psr.c
> @@ -40,10 +40,11 @@ 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
> +
> +typedef struct {
> +	int x, y;
> +	int w, h;
> +} pos_t;
>  
>  /* Common test data. */
>  typedef struct data {
> @@ -138,6 +139,29 @@ static void draw_color_cursor(igt_fb_t *fb, int size, double r, double g, double
>  	igt_put_cairo_ctx(cr);
>  }
>  
> +/* update the given framebuffer and draw colorful strip in new position */
> +static void update_color_strip(igt_fb_t *fb, pos_t *old, pos_t *new, double r, double g, double b)
> +{
> +	cairo_t *cr;
> +
> +	if (!fb || !new || !old)
> +		return;
> +
> +	cr = igt_get_cairo_ctx(fb->fd, fb);
> +	igt_assert_f(cr, "Failed to get cairo context\n");
> +
> +	/**
> +	 * we'd draw the strip in the new position w/ given color
> +	 * and make the background of the framebuffer as black
> +	 * - render black BG in the old position of strip instead of rendering the whole FB
> +	 * - render colorful strip in the new position
> +	 */
> +	igt_paint_color(cr, old->x, old->y, old->w, old->h, .0, .0, .0);
> +	igt_paint_color(cr, new->x, new->y, new->w, new->h, r, g, b);
> +
> +	igt_put_cairo_ctx(cr);
> +}
> +
>  /* Common test setup. */
>  static void test_init(data_t *data)
>  {
> @@ -314,12 +338,12 @@ static void run_check_psr(data_t *data, bool test_null_crtc) {
>  static void run_check_psr_su_mpo(data_t *data)
>  {
>  	int edp_idx = check_conn_type(data, DRM_MODE_CONNECTOR_eDP);
> -	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;
>  	int frame_rate = 0;
> +	pos_t old[2], new;
>  
>  	/* skip the test run if no eDP sink detected */
>  	igt_skip_on_f(edp_idx == -1, "no eDP connector found\n");
> @@ -327,6 +351,10 @@ static void run_check_psr_su_mpo(data_t *data)
>  	/* init */
>  	test_init(data);
>  	frame_rate = data->mode->vrefresh;
> +	memset(&old, 0, sizeof(pos_t) * 2);
> +	memset(&new, 0, sizeof(pos_t));
> +	old[0].w = old[1].w = new.w = 30;
> +	old[0].h = old[1].h = new.h = data->pfb_h;
>  
>  	/* run the test i.i.f. eDP panel supports and kernel driver both support PSR-SU  */
>  	igt_skip_on(!psr_su_supported(data));
> @@ -347,25 +375,14 @@ static void run_check_psr_su_mpo(data_t *data)
>  	 */
>  	igt_create_color_fb(data->fd, data->w, data->h, DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_LINEAR,
>  			    1.0, 1.0, 1.0, &data->ov_fb[0]);
> -	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->pfb_w, data->pfb_h, 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->pfb_w, data->pfb_h, .0, .0, .0);
> -		/* foreground (megenta strip) */
> -		igt_paint_color(cr, i * strip_w, 0, strip_w, data->pfb_h, 1.0, .0, 1.0);
> -
> -		igt_put_cairo_ctx(cr);
> -	}
> +	igt_create_color_fb(data->fd, data->pfb_w, data->pfb_h, DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
> +			    .0, .0, .0, &data->pm_fb[0]);
> +	igt_create_color_fb(data->fd, data->pfb_w, data->pfb_h, DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
> +			    .0, .0, .0, &data->pm_fb[1]);
>  
>  	/* tie fbs to planes and set position/size/blending */
>  	igt_plane_set_fb(data->overlay, &data->ov_fb[0]);
> -	igt_plane_set_fb(data->primary, &rect_fb[0]);
> +	igt_plane_set_fb(data->primary, &data->pm_fb[1]);
>  	igt_plane_set_position(data->primary, 0, 0);
>  	igt_plane_set_size(data->primary, data->pfb_w, data->pfb_h);
>  
> @@ -389,23 +406,28 @@ static void run_check_psr_su_mpo(data_t *data)
>  	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];
> +		flip_fb = &data->pm_fb[i & 1];
> +		/* draw the color strip onto primary plane FB */
> +		update_color_strip(flip_fb, &old[i & 1], &new, 1.0, .0, 1.0);
>  
>  		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);
> +		ret = igt_display_try_commit_atomic(&data->display, DRM_MODE_PAGE_FLIP_EVENT, NULL);
>  		igt_require(ret == 0);
>  		kmstest_wait_for_pageflip(data->fd);
> +
> +		/* update strip position */
> +		old[i & 1].x = new.x;
> +		new.x += 3;
> +		new.x = (new.x + new.w > data->pfb_w) ? 0 : new.x;
>  	}
>  
>  	/* fini */
>  	igt_remove_fb(data->fd, &ref_fb);
>  	igt_remove_fb(data->fd, &data->ov_fb[0]);
> -	for (int i = 0; i < N_MPO_TEST_RECT_FB; ++i)
> -		igt_remove_fb(data->fd, &rect_fb[i]);
> +	igt_remove_fb(data->fd, &data->pm_fb[0]);
> +	igt_remove_fb(data->fd, &data->pm_fb[1]);
>  	test_fini(data);
>  }
>  



More information about the igt-dev mailing list