[igt-dev] [PATCH i-g-t 3/3] tests: Add new PSR2 selective fetch test

Mun, Gwan-gyeong gwan-gyeong.mun at intel.com
Wed Dec 16 10:50:47 UTC 2020


On Tue, 2020-12-08 at 22:31 +0530, Pankaj Bharadiya wrote:
> Selective fetch reduces display engine use of memory bandwidth
> by only fetching (reading from memory) the updated regions of the
> frame
> buffer and sending those updated regions to a panel with a PSR2
> capability.
> 
> The FB_DAMAGE_CLIPS plane property provides user-space a way inform
> kernel about the updated regions.
> 
> Add new test to verify selective fetch by using FB_DAMAGE_CLIPS
> property
> to send  updated regions.
> 
> changes since v1:
> * alloc enough clips for all tests in stack and reuse (Jose)
> * set damage clip along with draw, refactor code, rename
>   variables, etc (Jose)
> 
> Signed-off-by: Pankaj Bharadiya <
> pankaj.laxminarayan.bharadiya at intel.com>
> ---
>  tests/Makefile.sources |   1 +
>  tests/kms_psr2_sf.c    | 649
> +++++++++++++++++++++++++++++++++++++++++
>  tests/meson.build      |   1 +
>  3 files changed, 651 insertions(+)
>  create mode 100644 tests/kms_psr2_sf.c
> 
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index 15fb56048..e7e399165 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -80,6 +80,7 @@ TESTS_progs = \
>  	kms_properties \
>  	kms_psr \
>  	kms_psr2_su \
> +	kms_psr2_sf \
>  	kms_pwrite_crc \
>  	kms_rmfb \
>  	kms_rotation_crc \
> diff --git a/tests/kms_psr2_sf.c b/tests/kms_psr2_sf.c
> new file mode 100644
> index 000000000..296ed8476
> --- /dev/null
> +++ b/tests/kms_psr2_sf.c
> @@ -0,0 +1,649 @@
> +/*
> + * Copyright © 2020 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person
> obtaining a
> + * copy of this software and associated documentation files (the
> "Software"),
> + * to deal in the Software without restriction, including without
> limitation
> + * the rights to use, copy, modify, merge, publish, distribute,
> sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom
> the
> + * Software is furnished to do so, subject to the following
> conditions:
> + *
> + * The above copyright notice and this permission notice (including
> the next
> + * paragraph) shall be included in all copies or substantial
> portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO
> EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
> OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +
> +#include "igt.h"
> +#include "igt_sysfs.h"
> +#include "igt_psr.h"
> +#include <errno.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include "intel_bufmgr.h"
> +
> +IGT_TEST_DESCRIPTION("Tests to varify PSR2 selective fetch by
> sending multiple"
> +		     " damaged areas");
> +
> +#define SQUARE_SIZE 100
> +
> +#define CUR_SIZE 64
> +#define MAX_DAMAGE_AREAS 5
> +
> +enum operations {
> +	PLANE_UPDATE,
> +	PLANE_MOVE,
> +	OVERLAY_PRIM_UPDATE
> +};
> +
Hi, can you also add use case which uses igt_fb_set_position()?

> +enum plane_move_postion {
> +	POS_TOP_LEFT,
> +	POS_TOP_RIGHT,
> +	POS_BOTTOM_LEFT,
> +	POS_BOTTOM_RIGHT
> +};
> +
> +typedef struct {
> +	int drm_fd;
> +	int debugfs_fd;
> +	igt_display_t display;
> +	drm_intel_bufmgr *bufmgr;
> +	drmModeModeInfo *mode;
> +	igt_output_t *output;
> +	struct igt_fb fb_primary, fb_overlay, fb_cursor;
> +	struct igt_fb fb_test;
> +	int damage_area_count;
> +	struct drm_mode_rect plane_update_clip[MAX_DAMAGE_AREAS];
> +	struct drm_mode_rect plane_move_clip;
> +	struct drm_mode_rect cursor_clip;
> +	enum operations op;
> +	enum plane_move_postion pos;
> +	int test_plane_id;
> +	igt_plane_t *test_plane;
> +	cairo_t *cr;
> +} data_t;
> +
> +static const char *op_str(enum operations op)
> +{
> +	static const char * const name[] = {
> +		[PLANE_UPDATE] = "plane-update",
> +		[PLANE_MOVE] = "plane-move",
> +		[OVERLAY_PRIM_UPDATE] = "overlay-primary-update",
> +	};
> +
> +	return name[op];
> +}
> +
> +static void setup_output(data_t *data)
> +{
> +	igt_display_t *display = &data->display;
> +	igt_output_t *output;
> +	enum pipe pipe;
> +
> +	for_each_pipe_with_valid_output(display, pipe, output) {
> +		drmModeConnectorPtr c = output->config.connector;
> +
> +		if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
> +			continue;
> +
> +		igt_output_set_pipe(output, pipe);
> +		data->output = output;
> +		data->mode = igt_output_get_mode(output);
> +
> +		return;
> +	}
> +}
> +
> +static void display_init(data_t *data)
> +{
> +	igt_display_require(&data->display, data->drm_fd);
> +	setup_output(data);
> +}
> +
> +static void display_fini(data_t *data)
> +{
> +	igt_display_fini(&data->display);
> +}
> +
> +static void draw_rect(data_t *data, igt_fb_t *fb, int x, int y, int
> w, int h,
> +			double r, double g, double b, double a)
> +{
> +	cairo_t *cr;
> +
> +	cr = igt_get_cairo_ctx(data->drm_fd, fb);
> +	igt_paint_color_alpha(cr, x, y, w, h, r, g, b, a);
> +	igt_put_cairo_ctx(cr);
> +}
> +
> +static void set_clip(struct drm_mode_rect *clip, int x, int y, int
> width,
> +		     int height)
> +{
> +	clip->x1 = x;
> +	clip->y1 = y;
> +	clip->x2 = x + width;
> +	clip->y2 = y + height;
> +}
> +
> +static void plane_update_setup_squares(data_t *data, igt_fb_t *fb,
> uint32_t h,
> +				       uint32_t v)
> +{
> +	int x, y;
> +	int width = SQUARE_SIZE;
> +	int height = SQUARE_SIZE;
> +
> +	switch (data->damage_area_count) {
> +	case 5:
> +		/*Bottom right corner*/
> +		x = h - SQUARE_SIZE;
> +		y = v - SQUARE_SIZE;
> +
> +		draw_rect(data, fb, x, y, width, height, 1.0, 1.0, 1.0,
> 1.0);
> +		set_clip(&data->plane_update_clip[4], x, y, width,
> height);
> +	case 4:
> +		/*Bottom left corner*/
> +		x = 0;
> +		y = v - SQUARE_SIZE;
> +
> +		draw_rect(data, fb, x, y, width, height, 1.0, 1.0, 1.0,
> 1.0);
> +		set_clip(&data->plane_update_clip[3], x, y, width,
> height);
> +	case 3:
> +		/*Top right corner*/
> +		x = h - SQUARE_SIZE;
> +		y = 0;
> +
> +		draw_rect(data, fb, x, y, width, height, 1.0, 1.0, 1.0,
> 1.0);
> +		set_clip(&data->plane_update_clip[2], x, y, width,
> height);
> +	case 2:
> +		/*Top left corner*/
> +		x = 0;
> +		y = 0;
> +
> +		draw_rect(data, fb, x, y, width, height, 1.0, 1.0, 1.0,
> 1.0);
> +		set_clip(&data->plane_update_clip[1], x, y, width,
> height);
> +	case 1:
> +		/*Center*/
> +		x = h/2 - SQUARE_SIZE/2;
> +		y = v/2 - SQUARE_SIZE/2;
> +
> +		draw_rect(data, fb, x, y, width, height, 1.0, 1.0, 1.0,
> 1.0);
> +		set_clip(&data->plane_update_clip[0], x, y, width,
> height);
> +		break;
> +	default:
> +		igt_assert(false);
> +	}
> +}
> +
> +static void plane_move_setup_square(data_t *data, igt_fb_t *fb,
> uint32_t h,
> +				       uint32_t v)
> +{
> +	int x = 0, y = 0;
> +
> +	switch (data->pos) {
> +	case POS_TOP_LEFT:
> +		/*Bottom right corner*/
it seems that the comments do not match enum name.
> +		x = h - SQUARE_SIZE;
> +		y = v - SQUARE_SIZE;
> +		break;
> +	case POS_TOP_RIGHT:
> +		/*Bottom left corner*/
> +		x = 0;
> +		y = v - SQUARE_SIZE;
> +		break;
> +	case POS_BOTTOM_LEFT:
> +		/*Top right corner*/
> +		x = h - SQUARE_SIZE;
> +		y = 0;
> +		break;
> +	case POS_BOTTOM_RIGHT:
> +		/*Top left corner*/
> +		x = 0;
> +		y = 0;
> +		break;
> +	default:
> +		igt_assert(false);
> +	}
> +
> +	draw_rect(data, fb, x, y,
> +		  SQUARE_SIZE, SQUARE_SIZE, 1.0, 1.0, 1.0, 1.0);
> +	set_clip(&data->plane_move_clip, x, y, SQUARE_SIZE,
> SQUARE_SIZE);
> +}
> +
> +static void prepare(data_t *data)
> +{
> +	igt_plane_t *primary, *sprite = NULL, *cursor = NULL;
> +
> +	/* all green frame */
> +	igt_create_color_fb(data->drm_fd,
> +			    data->mode->hdisplay, data->mode->vdisplay,
> +			    DRM_FORMAT_XRGB8888,
> +			    LOCAL_DRM_FORMAT_MOD_NONE,
> +			    0.0, 1.0, 0.0,
> +			    &data->fb_primary);
> +
> +	primary = igt_output_get_plane_type(data->output,
> +			DRM_PLANE_TYPE_PRIMARY);
> +
> +	switch (data->test_plane_id) {
> +	case DRM_PLANE_TYPE_OVERLAY:
> +		sprite = igt_output_get_plane_type(data->output,
> +						   DRM_PLANE_TYPE_OVERL
> AY);
> +		/*All blue plane*/
> +		igt_create_color_fb(data->drm_fd,
> +				    data->mode->hdisplay/2,
> +				    data->mode->vdisplay/2,
> +				    DRM_FORMAT_XRGB8888,
> +				    LOCAL_DRM_FORMAT_MOD_NONE,
> +				    0.0, 0.0, 1.0,
> +				    &data->fb_overlay);
> +
> +		igt_create_color_fb(data->drm_fd,
> +				    data->mode->hdisplay/2,
> +				    data->mode->vdisplay/2,
> +				    DRM_FORMAT_XRGB8888,
> +				    LOCAL_DRM_FORMAT_MOD_NONE,
> +				    0.0, 0.0, 1.0,
> +				    &data->fb_test);
> +
> +		if (data->op == PLANE_MOVE) {
> +			plane_move_setup_square(data, &data->fb_test,
> +					   data->mode->hdisplay/2,
> +					   data->mode->vdisplay/2);
> +
> +		} else {
> +			plane_update_setup_squares(data, &data-
> >fb_test,
> +					   data->mode->hdisplay/2,
> +					   data->mode->vdisplay/2);
> +		}
> +
> +		igt_plane_set_fb(sprite, &data->fb_overlay);
> +		data->test_plane = sprite;
> +		break;
> +
> +	case DRM_PLANE_TYPE_PRIMARY:
> +		igt_create_color_fb(data->drm_fd,
> +			    data->mode->hdisplay, data->mode->vdisplay,
> +			    DRM_FORMAT_XRGB8888,
> +			    LOCAL_DRM_FORMAT_MOD_NONE,
> +			    0.0, 1.0, 0.0,
> +			    &data->fb_test);
> +
> +		plane_update_setup_squares(data, &data->fb_test,
> +					   data->mode->hdisplay,
> +					   data->mode->vdisplay);
> +		data->test_plane = primary;
> +
> +		if (data->op == OVERLAY_PRIM_UPDATE) {
> +			sprite = igt_output_get_plane_type(data-
> >output,
> +						   DRM_PLANE_TYPE_OVERL
> AY);
> +
> +			igt_create_color_fb(data->drm_fd,
> +					    data->mode->hdisplay,
> +					    data->mode->vdisplay,
> +					    DRM_FORMAT_XRGB8888,
> +					    LOCAL_DRM_FORMAT_MOD_NONE,
> +					    0.0, 0.0, 1.0,
> +					    &data->fb_overlay);
> +
> +			igt_plane_set_fb(sprite, &data->fb_overlay);
> +			igt_plane_set_prop_value(sprite,
> IGT_PLANE_ALPHA,
> +						 0x6060);
> +		}
> +		break;
> +
> +	case DRM_PLANE_TYPE_CURSOR:
> +		cursor = igt_output_get_plane_type(data->output,
> +						   DRM_PLANE_TYPE_CURSO
> R);
> +		igt_plane_set_position(cursor, 0, 0);
> +
> +		igt_create_fb(data->drm_fd, CUR_SIZE, CUR_SIZE,
> +			      DRM_FORMAT_ARGB8888,
> LOCAL_DRM_FORMAT_MOD_NONE,
> +			      &data->fb_cursor);
> +
> +		draw_rect(data, &data->fb_cursor, 0, 0, CUR_SIZE,
> CUR_SIZE,
> +			    0.0, 0.0, 1.0, 1.0);
> +
> +		igt_create_fb(data->drm_fd, CUR_SIZE, CUR_SIZE,
> +			      DRM_FORMAT_ARGB8888,
> LOCAL_DRM_FORMAT_MOD_NONE,
> +			      &data->fb_test);
> +
> +		draw_rect(data, &data->fb_test, 0, 0, CUR_SIZE,
> CUR_SIZE,
> +			    1.0, 1.0, 1.0, 1.0);
> +
> +		set_clip(&data->cursor_clip, 0, 0, CUR_SIZE, CUR_SIZE);
> +		igt_plane_set_fb(cursor, &data->fb_cursor);
> +		data->test_plane = cursor;
> +		break;
> +	default:
> +		igt_assert(false);
> +	}
> +
> +	igt_plane_set_fb(primary, &data->fb_primary);
> +
> +	igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +}
> +
> +static inline void manual(const char *expected)
> +{
> +	igt_debug_manual_check("all", expected);
> +}
> +
> +static void plane_update_expected_output(int plane_type, int
> box_count)
> +{
> +	char expected[64] = {};
> +
> +	switch (plane_type) {
> +	case DRM_PLANE_TYPE_PRIMARY:
> +		sprintf(expected, "screen Green with %d White box(es)",
> +			box_count);
> +		break;
> +	case DRM_PLANE_TYPE_OVERLAY:
> +		sprintf(expected,
> +			"screen Green with Blue box and %d White
> box(es)",
> +			box_count);
> +		break;
> +	case DRM_PLANE_TYPE_CURSOR:
> +		sprintf(expected, "screen Green with %d White box(es)",
> +			box_count);
> +		break;
> +	default:
> +		igt_assert(false);
> +	}
> +
> +	manual(expected);
> +}
> +
> +static void plane_move_expected_output(enum plane_move_postion pos)
> +{
> +	char expected[64] = {};
> +
> +	switch (pos) {
> +	case POS_TOP_LEFT:
> +		sprintf(expected,
> +			"screen Green with Blue box on top left corner
> and White box");
> +		break;
> +	case POS_TOP_RIGHT:
> +		sprintf(expected,
> +			"screen Green with Blue box on top right corner
> and White box");
> +		break;
> +	case POS_BOTTOM_LEFT:
> +		sprintf(expected,
> +			"screen Green with Blue box on bottom left
> corner and White box");
> +		break;
> +	case POS_BOTTOM_RIGHT:
> +		sprintf(expected,
> +			"screen Green with Blue box on bottom right
> corner and White box");
> +		break;
> +	default:
> +		igt_assert(false);
> +	}
> +
> +	manual(expected);
> +}
> +
> +static void overlay_prim_update_expected_output(int box_count)
> +{
> +	char expected[64] = {};
> +
> +	sprintf(expected,
> +		"screen Green with Blue overlay, %d light Blue
> box(es)",
> +		box_count);
> +
> +	manual(expected);
> +
> +}
> +
> +static void expected_output(data_t *data)
> +{
> +	switch (data->op) {
> +	case PLANE_MOVE:
> +		plane_move_expected_output(data->pos);
> +		break;
> +	case PLANE_UPDATE:
> +		plane_update_expected_output(data->test_plane_id,
> +					     data->damage_area_count);
> +		break;
> +	case OVERLAY_PRIM_UPDATE:
> +		overlay_prim_update_expected_output(data-
> >damage_area_count);
> +		break;
> +	default:
> +		igt_assert(false);
> +	}
> +}
> +
> +static void damaged_plane_move(data_t *data)
> +{
> +	igt_plane_t *test_plane = data->test_plane;
> +	uint32_t h = data->mode->hdisplay;
> +	uint32_t v = data->mode->vdisplay;
> +
> +	igt_plane_set_fb(test_plane, &data->fb_test);
> +
> +	if (data->test_plane_id == DRM_PLANE_TYPE_OVERLAY) {
> +		h = h/2;
> +		v = v/2;
> +	}
> +
> +	igt_plane_replace_prop_blob(test_plane,
> IGT_PLANE_FB_DAMAGE_CLIPS,
> +				    &data->plane_move_clip,
> +				    sizeof(struct drm_mode_rect));
> +
> +	switch (data->pos) {
> +	case POS_TOP_LEFT:
> +		igt_plane_set_position(data->test_plane, 0, 0);
> +		break;
> +	case POS_TOP_RIGHT:
> +		igt_plane_set_position(data->test_plane,
> +				       data->mode->hdisplay/2, 0);
> +		break;
> +	case POS_BOTTOM_LEFT:
> +		igt_plane_set_position(data->test_plane, 0,
> +				       data->mode->vdisplay/2);
> +		break;
> +	case POS_BOTTOM_RIGHT:
> +		igt_plane_set_position(data->test_plane,
> +				       data->mode->hdisplay/2,
> +				       data->mode->vdisplay/2);
> +		break;
> +	default:
> +		igt_assert(false);
> +	}
> +
> +	igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +
> +	igt_assert(psr_wait_entry(data->debugfs_fd, PSR_MODE_2));
> +
> +	expected_output(data);
> +}
> +
> +static void damaged_plane_update(data_t *data)
> +{
> +	igt_plane_t *test_plane = data->test_plane;
> +	uint32_t h = data->mode->hdisplay;
> +	uint32_t v = data->mode->vdisplay;
> +
> +	igt_plane_set_fb(test_plane, &data->fb_test);
> +
> +	if (data->test_plane_id == DRM_PLANE_TYPE_OVERLAY) {
> +		h = h/2;
> +		v = v/2;
> +	}
> +
> +	if (data->test_plane_id == DRM_PLANE_TYPE_CURSOR)
> +		igt_plane_replace_prop_blob(test_plane,
> +					    IGT_PLANE_FB_DAMAGE_CLIPS,
> +					    &data->cursor_clip,
> +					    sizeof(struct
> drm_mode_rect));
> +	else
> +		igt_plane_replace_prop_blob(test_plane,
> +					    IGT_PLANE_FB_DAMAGE_CLIPS,
> +					    &data->plane_update_clip,
> +					    sizeof(struct
> drm_mode_rect)*
> +					    data->damage_area_count);
> +
> +	igt_plane_set_position(data->test_plane, 0, 0);
> +	igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +
> +	igt_assert(psr_wait_entry(data->debugfs_fd, PSR_MODE_2));
> +
> +	expected_output(data);
> +}
> +
> +static void run(data_t *data)
> +{
> +	igt_assert(psr_wait_entry(data->debugfs_fd, PSR_MODE_2));
> +
> +	switch (data->op) {
> +	case PLANE_UPDATE:
> +	case OVERLAY_PRIM_UPDATE:
> +		damaged_plane_update(data);
> +		break;
> +	case PLANE_MOVE:
> +		damaged_plane_move(data);
> +		break;
> +	default:
> +		igt_assert(false);
> +	}
> +}
> +
> +static void cleanup(data_t *data)
> +{
> +	igt_plane_t *primary;
> +	igt_plane_t *sprite;
> +
> +	primary = igt_output_get_plane_type(data->output,
> +					    DRM_PLANE_TYPE_PRIMARY);
> +
> +	igt_plane_set_fb(primary, NULL);
> +
> +	if (data->test_plane_id != DRM_PLANE_TYPE_PRIMARY) {
> +		igt_plane_set_position(data->test_plane, 0, 0);
> +		igt_plane_set_fb(data->test_plane, NULL);
> +	}
> +
> +	if (data->op == OVERLAY_PRIM_UPDATE) {
> +		sprite = igt_output_get_plane_type(data->output,
> +				DRM_PLANE_TYPE_OVERLAY);
> +		igt_plane_set_position(sprite, 0, 0);
> +		igt_plane_set_fb(sprite, NULL);
> +	}
> +
> +	igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +
> +	igt_remove_fb(data->drm_fd, &data->fb_primary);
> +	igt_remove_fb(data->drm_fd, &data->fb_overlay);
> +	igt_remove_fb(data->drm_fd, &data->fb_cursor);
> +	igt_remove_fb(data->drm_fd, &data->fb_test);
> +}
> +
> +igt_main
> +{
> +	data_t data = {};
> +	int i;
> +
> +	igt_fixture {
> +		int r;
> +
> +		data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
> +		data.debugfs_fd = igt_debugfs_dir(data.drm_fd);
> +		kmstest_set_vt_graphics_mode();
> +
> +		igt_require_f(psr_sink_support(data.drm_fd,
> +					       data.debugfs_fd,
> PSR_MODE_2),
> +			      "Sink does not support PSR2\n");
> +
> +		igt_require_f(psr2_selective_fetch_check(data.debugfs_f
> d),
> +			      "PSR2 selective fetch not enabled\n");
> +
> +		data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd,
> 4096);
> +		igt_assert(data.bufmgr);
> +		drm_intel_bufmgr_gem_enable_reuse(data.bufmgr);
> +
> +		display_init(&data);
> +
> +		/* Test if PSR2 can be enabled */
> +		igt_require_f(psr_enable(data.drm_fd,
> +					 data.debugfs_fd, PSR_MODE_2),
> +			      "Error enabling PSR2\n");
> +
> +		data.damage_area_count = MAX_DAMAGE_AREAS;
> +		data.op = PLANE_UPDATE;
> +		data.test_plane_id = DRM_PLANE_TYPE_PRIMARY;
> +		prepare(&data);
> +		r = psr_wait_entry(data.debugfs_fd, PSR_MODE_2);
> +		cleanup(&data);
> +		if (!r)
> +			psr_print_debugfs(data.debugfs_fd);
> +		igt_require_f(r, "PSR2 can not be enabled\n");
> +	}
> +
> +	/* Verify primary plane selective fetch */
> +	for (i = 1; i <= MAX_DAMAGE_AREAS; i++) {
> +		igt_subtest_f("primary-%s-sf-dmg-area-%d",
> op_str(data.op), i) {
> +			data.damage_area_count = i;
> +			data.test_plane_id = DRM_PLANE_TYPE_PRIMARY;
> +			prepare(&data);
> +			run(&data);
> +			cleanup(&data);
> +		}
> +	}
> +
> +	/* Verify overlay plane selective fetch */
> +	for (i = 1; i <= MAX_DAMAGE_AREAS; i++) {
> +		igt_subtest_f("overlay-%s-sf-dmg-area-%d",
> op_str(data.op), i) {
> +			data.damage_area_count = i;
> +			data.test_plane_id = DRM_PLANE_TYPE_OVERLAY;
> +			prepare(&data);
> +			run(&data);
> +			cleanup(&data);
> +		}
> +	}
> +
> +	/* Verify overlay plane selective fetch */
> +	igt_subtest_f("cursor-%s-sf", op_str(data.op)) {
> +		data.damage_area_count = 1;
> +		data.test_plane_id = DRM_PLANE_TYPE_CURSOR;
> +		prepare(&data);
> +		run(&data);
> +		cleanup(&data);
> +	}
> +
> +	/* Only for overlay plane */
> +	data.op = PLANE_MOVE;
> +	/* Verify overlay plane move selective fetch */
> +	for (i = POS_TOP_LEFT; i <= POS_BOTTOM_RIGHT ; i++) {
> +		igt_subtest_f("%s-sf-dmg-area-%d", op_str(data.op), i)
> {
> +			data.pos = i;
> +			data.test_plane_id = DRM_PLANE_TYPE_OVERLAY;
> +			prepare(&data);
> +			run(&data);
> +			cleanup(&data);
> +		}
> +	}
> +
> +	/* Verify primary plane selective fetch with overplay plane
> blended */
> +	data.op = OVERLAY_PRIM_UPDATE;
> +	for (i = 1; i <= MAX_DAMAGE_AREAS; i++) {
> +		igt_subtest_f("%s-sf-dmg-area-%d", op_str(data.op), i)
> {
> +			data.damage_area_count = i;
> +			data.test_plane_id = DRM_PLANE_TYPE_PRIMARY;
> +			prepare(&data);
> +			run(&data);
> +			cleanup(&data);
> +		}
> +	}
> +
> +	igt_fixture {
> +		close(data.debugfs_fd);
> +		drm_intel_bufmgr_destroy(data.bufmgr);
> +		display_fini(&data);
> +	}
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index a2decf4ab..4cab294b8 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -64,6 +64,7 @@ test_progs = [
>  	'kms_properties',
>  	'kms_psr',
>  	'kms_psr2_su',
> +	'kms_psr2_sf',
>  	'kms_pwrite_crc',
>  	'kms_rmfb',
>  	'kms_rotation_crc',

And this igt test case is needed for testing this feature (
https://patchwork.freedesktop.org/series/84910/ )
when it comes to getting the latest revision of the kernel patch, I'll leave more comments which include the
test result.

Br,
G.G.


More information about the igt-dev mailing list