[PATCH i-g-t 2/2] RFC FBC dirty rect tests

Vinod Govindapillai vinod.govindapillai at intel.com
Fri Feb 7 12:27:29 UTC 2025


set_fb
set_damage
outside visible rect
color strips
dirtyfb + dmamage area

Signed-off-by: Vinod Govindapillai <vinod.govindapillai at intel.com>
---
 tests/intel/kms_fbc_dirty_rect.c | 530 ++++++++++++++++++++++++-------
 1 file changed, 417 insertions(+), 113 deletions(-)

diff --git a/tests/intel/kms_fbc_dirty_rect.c b/tests/intel/kms_fbc_dirty_rect.c
index b05367011..f84a6e504 100644
--- a/tests/intel/kms_fbc_dirty_rect.c
+++ b/tests/intel/kms_fbc_dirty_rect.c
@@ -13,8 +13,21 @@
  * Test category: functionality test
  */
 
+#include <sys/types.h>
+
 #include "igt.h"
+
+#include "igt_sysfs.h"
+#include "i915/gem.h"
+#include "i915/gem_create.h"
+#include "i915/intel_drrs.h"
+#include "igt_psr.h"
+
 #include "i915/intel_fbc.h"
+#include "intel_mocs.h"
+#include "intel_pat.h"
+
+#include "xe/xe_query.h"
 
 enum operations {
 	FRONTBUFFER,
@@ -24,21 +37,36 @@ enum operations {
  * SUBTEST: fbc-dirty-rectangle-basic
  * Description: Sanity test to verify FBC DR by sending multiple damaged areas with non psr modes
  * Functionality: fbc
+ * 
+ * SUBTEST: fbc-dirty-rectangle-out-visible-area
+ * Description: Sanity test to verify FBC DR by sending multiple damaged areas with non psr modes
+ * Functionality: fbc
+ *
+ * SUBTEST: fbc-dirty-rectangle-dirtyfb-tests
+ * Description: Sanity test to verify FBC DR by sending multiple damaged areas with non psr modes
+ * Functionality: fbc
  *
  * SUBTEST: fbc-dirty-rectangle-different-formats
  * Description: Sanity test to verify FBC DR by sending multiple
  *              damaged areas with different formats.
  * Functionality: fbc
  *
- * SUBTEST: fbc-dirty-rectangle-dirtyfb-ioctl
- * Description: Sanity test to verify FBC DR by sending
- *              multiple damaged areas with dirtyfb ioctl with fbc enabled.
- * Functionality: fbc
  */
 
+#ifndef PAGE_ALIGN
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+#define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE)
+#endif
+
 #define SQUARE_SIZE 100
 #define SQUARE_OFFSET 100
 #define SQUARE_OFFSET_2 600
+#define SQUARE_OFFSET_OUTSIDE_Y 1850 
+
+#define N_STRIPS	4
+#define STRIP_H		300
 
 typedef struct {
 	int drm_fd;
@@ -63,6 +91,13 @@ typedef struct {
 	} feature;
 } data_t;
 
+enum color {
+	BLACK,
+	RED,
+	GREEN,
+	BLUE,
+	WHITE,
+};
 
 static void set_damage_clip(struct drm_mode_rect *damage, int x1, int y1, int x2, int y2)
 {
@@ -72,14 +107,40 @@ static void set_damage_clip(struct drm_mode_rect *damage, int x1, int y1, int x2
 	damage->y2 = y2;
 }
 
-static void dirty_rect_create_fb(data_t *data, struct igt_fb *fb, int nrects,
-				 struct drm_mode_rect *rect)
+static void set_damage_clip_w(struct drm_mode_rect *damage, int x1, int y1, int width, int height)
 {
-	cairo_t *cr;
+	set_damage_clip(damage, x1, y1, x1 + width, y1 + height);
+}
+
+static void debugfs_read_crtc(const char *param, char *buf, int len, data_t *data)
+{
+	int dir;
+	enum pipe pipe;
 
-	igt_create_color_fb(data->drm_fd, data->mode->hdisplay, data->mode->vdisplay,
-			    DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
-			    0.0, 0.0, 1.0, fb);
+	pipe = data->pipe;
+	dir = igt_debugfs_pipe_dir(data->drm_fd, pipe, O_DIRECTORY);
+	igt_require_fd(dir);
+	igt_debugfs_simple_read(dir, param, buf, len);
+	close(dir);
+}
+
+static bool fbc_is_compressing(data_t *data)
+{
+	char buf[128];
+
+	debugfs_read_crtc("i915_fbc_status", buf, sizeof(buf), data);
+	return strstr(buf, "\nCompressing: yes\n") != NULL;
+}
+
+static bool fbc_wait_for_compression(data_t *data)
+{
+	return igt_wait(fbc_is_compressing(data), 2000, 1);
+}
+
+static void dirty_rect_draw_white_rects(data_t *data, struct igt_fb *fb,
+					int nrects, struct drm_mode_rect *rect)
+{
+	cairo_t *cr;
 
 	if (!nrects || !rect)
 		return;
@@ -92,9 +153,274 @@ static void dirty_rect_create_fb(data_t *data, struct igt_fb *fb, int nrects,
 				      rect[i].y2 - rect[i].y1,
 				      1.0, 1.0, 1.0, 1.0);
 	}
+
 	igt_put_cairo_ctx(cr);
 }
 
+static void dirty_rect_create_fb(data_t *data, struct igt_fb *fb, int fb_width,
+				 int fb_height, enum color bg_color)
+{
+	switch (bg_color) {
+	case RED:
+		igt_create_color_fb(data->drm_fd, fb_width, fb_height,
+			    	    data->format, DRM_FORMAT_MOD_LINEAR,
+				    1.0, 0.0, 0.0, fb);
+		break;
+	
+	case GREEN:
+		igt_create_color_fb(data->drm_fd, fb_width, fb_height,
+			    	    data->format, DRM_FORMAT_MOD_LINEAR,
+				    0.0, 1.0, 0.0, fb);
+		break;
+
+	case BLUE:
+		igt_create_color_fb(data->drm_fd, fb_width, fb_height,
+			    	    data->format, DRM_FORMAT_MOD_LINEAR,
+				    0.0, 0.0, 1.0, fb);
+		break;
+
+	case WHITE:
+		igt_create_color_fb(data->drm_fd, fb_width, fb_height,
+			    	    data->format, DRM_FORMAT_MOD_LINEAR,
+				    1.0, 1.0, 1.0, fb);
+		break;
+	default:
+	case BLACK:
+		igt_create_color_fb(data->drm_fd, fb_width, fb_height,
+			    	    data->format, DRM_FORMAT_MOD_LINEAR,
+				    0.0, 0.0, 0.0, fb);
+		break;
+	}
+}
+
+static void
+set_damage_area(igt_plane_t *plane,  struct drm_mode_rect *rects,
+		size_t length)
+{
+	igt_plane_replace_prop_blob(plane, IGT_PLANE_FB_DAMAGE_CLIPS, rects, length);
+}
+
+static void
+set_fb_and_collect_crc(data_t *data, igt_plane_t *plane, struct igt_fb *fb,
+		       igt_pipe_crc_t *pipe_crc, igt_crc_t *crc)
+{
+	igt_plane_set_fb(plane, fb);
+	igt_display_commit2(&data->display, COMMIT_ATOMIC);
+	igt_pipe_crc_collect_crc(pipe_crc, crc);
+	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
+					  IGT_LOG_WARN),
+					  "FBC is not enabled\n");
+}
+
+static void
+update_rect_with_dirtyfb(data_t *data, struct igt_fb *fb1, struct igt_fb *fb2,
+			 struct drm_mode_rect *rect)
+{
+	struct intel_buf *src, *dst;
+	struct intel_bb *ibb;
+	igt_spin_t *spin;
+	int r;
+	struct buf_ops *bops;
+	igt_render_copyfunc_t rendercopy;
+
+	bops = buf_ops_create(data->drm_fd);
+	rendercopy = igt_get_render_copyfunc(intel_get_drm_devid(data->drm_fd));
+
+	src = intel_buf_create_full(bops, fb1->gem_handle, fb1->width,
+				    fb1->height,
+				    igt_drm_format_to_bpp(fb1->drm_format),
+				    0,
+				    igt_fb_mod_to_tiling(fb1->modifier),
+				    0, fb1->size, 0, system_memory(data->drm_fd),
+				    intel_get_pat_idx_uc(data->drm_fd),
+				    DEFAULT_MOCS_INDEX);
+	dst = intel_buf_create_full(bops, fb2->gem_handle,
+				    fb2->width, fb2->height,
+				    igt_drm_format_to_bpp(fb2->drm_format),
+				    0, igt_fb_mod_to_tiling(fb2->modifier),
+				    0, fb2->size, 0, system_memory(data->drm_fd),
+				    intel_get_pat_idx_uc(data->drm_fd),
+				    DEFAULT_MOCS_INDEX);
+	ibb = intel_bb_create(data->drm_fd, PAGE_SIZE);
+
+	spin = igt_spin_new(data->drm_fd, .ahnd = ibb->allocator_handle);
+	igt_spin_set_timeout(spin, NSEC_PER_SEC);
+
+	rendercopy(ibb, src, rect->x1, rect->y1, rect->x2 - rect->x1,
+		   rect->y2 - rect->y1, dst, rect->x1, rect->y1);
+
+	/* Perfom dirtyfb right after initiating rendercopy/blitter */
+	r = drmModeDirtyFB(data->drm_fd, fb2->fb_id, NULL, 0);
+	igt_assert(r == 0 || r == -ENOSYS);
+
+	/* Ensure rendercopy/blitter is complete */
+	intel_bb_sync(ibb);
+		
+	igt_spin_free(data->drm_fd, spin);
+	intel_bb_destroy(ibb);
+	intel_buf_destroy(src);
+	intel_buf_destroy(dst);
+}
+
+static void fbc_dirty_rectangle_dirtyfb(data_t *data)
+{
+	igt_pipe_crc_t *pipe_crc = data->pipe_crc;
+	igt_display_t *display = &data->display;
+	igt_output_t *output = data->output;
+	igt_plane_t *primary;
+	drmModeModeInfo *mode;
+	struct igt_fb main_fb, fb2, fb3, fb4;
+	struct drm_mode_rect full_rect, rect1, rect2;
+	igt_crc_t main_crc, fb2_crc, fb3_crc, fb4_crc, crc;
+
+	mode = igt_output_get_mode(output);
+	igt_output_set_pipe(output, data->pipe);
+	if (!pipe_crc) {
+		pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe,
+					    IGT_PIPE_CRC_SOURCE_AUTO);
+		igt_assert(pipe_crc);
+	}
+	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+
+	set_damage_clip_w(&full_rect, 0, 0, mode->hdisplay, mode->vdisplay);
+	set_damage_clip_w(&rect1, SQUARE_OFFSET, SQUARE_OFFSET, SQUARE_SIZE,
+			  SQUARE_SIZE);
+	set_damage_clip_w(&rect2, SQUARE_OFFSET_2, SQUARE_OFFSET_2,
+			  SQUARE_SIZE, SQUARE_SIZE);
+
+	dirty_rect_create_fb(data, &main_fb, data->mode->hdisplay,
+			     data->mode->vdisplay, BLUE);
+	
+	dirty_rect_create_fb(data, &fb2, data->mode->hdisplay,
+			     data->mode->vdisplay, BLUE);
+	dirty_rect_draw_white_rects(data, &fb2, 1, &rect1);
+
+	dirty_rect_create_fb(data, &fb3, data->mode->hdisplay,
+			     data->mode->vdisplay, BLUE);
+	dirty_rect_draw_white_rects(data, &fb3, 1, &rect2);
+
+	dirty_rect_create_fb(data, &fb4, data->mode->hdisplay,
+			     data->mode->vdisplay, BLUE);
+	dirty_rect_draw_white_rects(data, &fb4, 1, &rect2);
+
+
+	/* 1st screen - Empty blue screen*/
+	set_damage_area(primary, &full_rect, sizeof(full_rect));
+	set_fb_and_collect_crc(data, primary, &main_fb, pipe_crc, &main_crc);
+
+	/* 2nd screen - 1st white rect at 100, 100 - using damage area */
+	set_damage_area(primary, &rect1, sizeof(rect1));
+	set_fb_and_collect_crc(data, primary, &fb2, pipe_crc, &fb2_crc);
+
+	/* 3rd screen - 2nd white rect at 600, 600 - using damage area. Now two white rects on screen */
+	set_damage_area(primary, &rect2, sizeof(rect2));
+	set_fb_and_collect_crc(data, primary, &fb3, pipe_crc, &fb3_crc);
+
+	/* 4th screen - clear the 2nd white rect at 600,600 with dirtyfb.
+	 * Copy rect2 area from main_fb to fb3. Then fb3 becomes whole blue
+	 */
+	update_rect_with_dirtyfb(data, &main_fb, &fb3, &rect2);
+	/* Now the screen must match 3rd screen - with both rects */
+	igt_pipe_crc_collect_crc(pipe_crc, &crc);
+	igt_assert_crc_equal(&crc, &main_crc);
+	
+	/* 5th screen - Copy the first rect at 100,100 with dirtyfb.
+	 * Copy rect1 area from fb2 to fb3. Then fb3 becomes one rect at 100,100
+	 */
+	update_rect_with_dirtyfb(data, &fb2, &fb3, &rect1);
+	/* Now the screen must match 2nd screen - with one rect 1t 100,100 */
+	igt_pipe_crc_collect_crc(pipe_crc, &crc);
+	igt_assert_crc_equal(&crc, &fb2_crc);
+
+	/* 6th screen - 2nd white rect at 600, 600 - using damage area. Now two white rects on screen */
+	set_damage_area(primary, &rect2, sizeof(rect2));
+	set_fb_and_collect_crc(data, primary, &fb4, pipe_crc, &fb4_crc);
+	/* Now the screen must match 3rd screen - with both rects */
+	igt_pipe_crc_collect_crc(pipe_crc, &crc);
+	igt_assert_crc_equal(&crc, &fb3_crc);
+
+	igt_plane_set_fb(primary, NULL);
+	igt_remove_fb(data->drm_fd, &main_fb);
+	igt_remove_fb(data->drm_fd, &fb2);
+	igt_remove_fb(data->drm_fd, &fb3);
+	igt_remove_fb(data->drm_fd, &fb4);
+	igt_display_commit2(display, COMMIT_ATOMIC);
+}
+
+static void fbc_dirty_rectangle_outside_visible_region(data_t *data)
+{
+	igt_pipe_crc_t *pipe_crc = data->pipe_crc;
+	igt_display_t *display = &data->display;
+	igt_output_t *output = data->output;
+	igt_plane_t *primary;
+	drmModeModeInfo *mode;
+	struct igt_fb main_fb, rect_1_fb, rect_2_fb, rect_3_fb;
+	struct drm_mode_rect rect1, full_rect, rect2, rect3;
+	igt_crc_t main_crc, rect1_crc, rect2_crc, rect3_crc;
+
+	mode = igt_output_get_mode(output);
+	igt_output_set_pipe(output, data->pipe);
+	if (!pipe_crc) {
+		pipe_crc = igt_pipe_crc_new(data->drm_fd, data->pipe,
+					    IGT_PIPE_CRC_SOURCE_AUTO);
+		igt_assert(pipe_crc);
+	}
+	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+
+	set_damage_clip(&full_rect, 0, 0, mode->hdisplay + 200,
+			mode->vdisplay + 200);
+	/* Rect Horizontally outside visible region */
+	set_damage_clip_w(&rect1, data->mode->hdisplay + 10, 100,
+			  SQUARE_SIZE, SQUARE_SIZE);
+	/* Rect verticall outside visible region */
+	set_damage_clip_w(&rect2, 10, data->mode->vdisplay + 50,
+			  SQUARE_SIZE, SQUARE_SIZE);
+	/* Rect Horizontally and vertically outside visible region */
+	set_damage_clip_w(&rect3, data->mode->hdisplay + 10,
+			  data->mode->vdisplay + 50, SQUARE_SIZE, SQUARE_SIZE);
+
+	dirty_rect_create_fb(data, &main_fb, data->mode->hdisplay + 200,
+			     data->mode->vdisplay + 200, GREEN);
+	
+	dirty_rect_create_fb(data, &rect_1_fb, data->mode->hdisplay + 200,
+			    data->mode->vdisplay + 200, GREEN);
+	dirty_rect_draw_white_rects(data, &rect_1_fb, 1, &rect1);
+
+	dirty_rect_create_fb(data, &rect_2_fb, data->mode->hdisplay + 200,
+			     data->mode->vdisplay + 200, GREEN);
+	dirty_rect_draw_white_rects(data, &rect_2_fb, 1, &rect2);
+
+	dirty_rect_create_fb(data, &rect_3_fb, data->mode->hdisplay + 200,
+			     data->mode->vdisplay + 200, GREEN);
+	dirty_rect_draw_white_rects(data, &rect_3_fb, 1, &rect3);
+
+	/* Main rect*/
+	set_damage_area(primary, &full_rect, sizeof(full_rect));
+	set_fb_and_collect_crc(data, primary, &main_fb, pipe_crc, &main_crc);
+
+	/* FB with a small square drawn at (hdisplay + 10, 100) (hdisplay + 10 + 100, 200) which is ourside hdisplay */
+	set_damage_area(primary, &rect1, sizeof(rect1));
+	set_fb_and_collect_crc(data, primary, &rect_1_fb, pipe_crc, &rect1_crc);
+	igt_assert_crc_equal(&rect1_crc, &main_crc);
+
+	/* FB with a small square drawn at (10, vdisplay + 50) (110, vdisplay + 50 +100) which is ourside vdisplay */
+	set_damage_area(primary, &rect2, sizeof(rect2));
+	set_fb_and_collect_crc(data, primary, &rect_2_fb, pipe_crc, &rect2_crc);
+	igt_assert_crc_equal(&rect2_crc, &main_crc);
+
+	/* FB with a small square drawn at ((hdisplay + 10, vdisplay + 50) ((hdisplay + 10 + 100, vdisplay + 50 +100) which is ourside hdisplay and vdisplay */
+	set_damage_area(primary, &rect3, sizeof(rect3));
+	set_fb_and_collect_crc(data, primary, &rect_3_fb, pipe_crc, &rect3_crc);
+	igt_assert_crc_equal(&rect3_crc, &main_crc);
+
+	igt_plane_set_fb(primary, NULL);
+	igt_remove_fb(data->drm_fd, &main_fb);
+	igt_remove_fb(data->drm_fd, &rect_1_fb);
+	igt_remove_fb(data->drm_fd, &rect_2_fb);
+	igt_remove_fb(data->drm_fd, &rect_3_fb);
+	igt_display_commit2(display, COMMIT_ATOMIC);
+}
+
 static void fbc_dirty_rectangle_complete_set(data_t *data)
 {
 	igt_pipe_crc_t *pipe_crc = data->pipe_crc;
@@ -111,7 +437,6 @@ static void fbc_dirty_rectangle_complete_set(data_t *data)
 	struct drm_mode_rect rect_combined[2];
 	struct drm_mode_rect full_rect;
 	igt_crc_t main_fb_crc, rect_1_fb_crc, rect_2_fb_crc, rect_combined_fb_crc, crc;
-	int ret;
 
 	mode = igt_output_get_mode(output);
 	igt_output_set_pipe(output, data->pipe);
@@ -130,94 +455,59 @@ static void fbc_dirty_rectangle_complete_set(data_t *data)
 	set_damage_clip(&rect_combined[0], rect1.x1, rect1.y1, rect1.x2, rect1.y2);
 	set_damage_clip(&rect_combined[1], rect2.x1, rect2.y1, rect2.x2, rect2.y2);
 
-	dirty_rect_create_fb(data, &main_fb, 0, NULL);
-	dirty_rect_create_fb(data, &rect_1_fb, 1, &rect1);
-	dirty_rect_create_fb(data, &rect_2_fb, 1, &rect2);
-	dirty_rect_create_fb(data, &rect_combined_fb, 2, rect_combined);
+	dirty_rect_create_fb(data, &main_fb, data->mode->hdisplay,
+			     data->mode->vdisplay, BLUE);
 
-	/* main_fb blank blue screen - get and store crc*/
-	igt_plane_replace_prop_blob(primary, IGT_PLANE_FB_DAMAGE_CLIPS,
-				    &full_rect, sizeof(full_rect));
-	dirty_rect_create_fb(data, &main_fb, 0, NULL);
-	dirty_rect_create_fb(data, &rect_1_fb, 1, &rect1);
-	dirty_rect_create_fb(data, &rect_2_fb, 1, &rect2);
-	dirty_rect_create_fb(data, &rect_combined_fb, 2, rect_combined);
+	dirty_rect_create_fb(data, &rect_1_fb, data->mode->hdisplay,
+			     data->mode->vdisplay, BLUE);
+	dirty_rect_draw_white_rects(data, &rect_1_fb, 1, &rect1);
+
+	dirty_rect_create_fb(data, &rect_2_fb, data->mode->hdisplay,
+			     data->mode->vdisplay, BLUE);
+	dirty_rect_draw_white_rects(data, &rect_2_fb, 1, &rect2);
+
+	dirty_rect_create_fb(data, &rect_combined_fb, data->mode->hdisplay,
+			     data->mode->vdisplay, BLUE);
+	dirty_rect_draw_white_rects(data, &rect_combined_fb,
+			     ARRAY_SIZE(rect_combined), rect_combined);
 
 	/* main_fb blank blue screen - get and store crc*/
-	igt_plane_replace_prop_blob(primary, IGT_PLANE_FB_DAMAGE_CLIPS,
-				    &full_rect, sizeof(full_rect));
-	igt_plane_set_fb(primary, &main_fb);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	igt_pipe_crc_collect_crc(pipe_crc, &main_fb_crc);
-	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
-					  IGT_LOG_WARN), "FBC is not enabled\n");
+	set_fb_and_collect_crc(data, primary, &main_fb, pipe_crc, &main_fb_crc);
 
 	/* Whole blue screen with one white rect and collect crc */
-	igt_plane_replace_prop_blob(primary, IGT_PLANE_FB_DAMAGE_CLIPS,
-				    &full_rect, sizeof(full_rect));
-	igt_plane_set_fb(primary, &rect_1_fb);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	igt_pipe_crc_collect_crc(pipe_crc, &rect_1_fb_crc);
-	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
-					  IGT_LOG_WARN), "FBC is not enabled\n");
+	set_damage_area(primary, &full_rect, sizeof(full_rect));
+	set_fb_and_collect_crc(data, primary, &rect_1_fb, pipe_crc,
+			       &rect_1_fb_crc);
 
 	/* Second white rect and collect crc */
-	igt_plane_replace_prop_blob(primary, IGT_PLANE_FB_DAMAGE_CLIPS,
-				    &full_rect, sizeof(full_rect));
-	igt_plane_set_fb(primary, &rect_2_fb);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	igt_pipe_crc_collect_crc(pipe_crc, &rect_2_fb_crc);
-	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
-					  IGT_LOG_WARN), "FBC is not enabled\n");
+	set_damage_area(primary, &full_rect, sizeof(full_rect));
+	set_fb_and_collect_crc(data, primary, &rect_2_fb, pipe_crc,
+			       &rect_2_fb_crc);
 
 	/* Both rects and collect crc */
-	igt_plane_replace_prop_blob(primary, IGT_PLANE_FB_DAMAGE_CLIPS,
-				    &full_rect, sizeof(full_rect));
-	igt_plane_set_fb(primary, &rect_combined_fb);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	igt_pipe_crc_collect_crc(pipe_crc, &rect_combined_fb_crc);
-	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
-					  IGT_LOG_WARN), "FBC is not enabled\n");
+	set_damage_area(primary, &full_rect, sizeof(full_rect));
+	set_fb_and_collect_crc(data, primary, &rect_combined_fb, pipe_crc,
+			       &rect_combined_fb_crc);
 
 	/* Put full blank screen back */
-	igt_plane_replace_prop_blob(primary, IGT_PLANE_FB_DAMAGE_CLIPS,
-				    &full_rect, sizeof(full_rect));
-	igt_plane_set_fb(primary, &main_fb);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	igt_pipe_crc_collect_crc(pipe_crc, &crc);
+	set_damage_area(primary, &full_rect, sizeof(full_rect));
+	set_fb_and_collect_crc(data, primary, &main_fb, pipe_crc, &crc);
 	igt_assert_crc_equal(&crc, &main_fb_crc);
-	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
-					  IGT_LOG_WARN), "FBC is not enabled\n");
 
 	/* Set combined rect - draw two white rects using damage area*/
-	igt_plane_replace_prop_blob(primary, IGT_PLANE_FB_DAMAGE_CLIPS,
-				    &rect_combined, sizeof(rect_combined));
-	igt_plane_set_fb(primary, &rect_combined_fb);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	igt_pipe_crc_collect_crc(pipe_crc, &crc);
+	set_damage_area(primary, rect_combined, sizeof(rect_combined));
+	set_fb_and_collect_crc(data, primary, &rect_combined_fb, pipe_crc, &crc);
 	igt_assert_crc_equal(&crc, &rect_combined_fb_crc);
-	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
-					  IGT_LOG_WARN), "FBC is not enabled\n");
 
 	/* Clear first rect using damage area. Only the second rect should be visible here! */
-	igt_plane_replace_prop_blob(primary, IGT_PLANE_FB_DAMAGE_CLIPS,
-				    &rect1, sizeof(rect1));
-	igt_plane_set_fb(primary, &main_fb);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	igt_pipe_crc_collect_crc(pipe_crc, &crc);
+	set_damage_area(primary, &rect1, sizeof(rect1));
+	set_fb_and_collect_crc(data, primary, &main_fb, pipe_crc, &crc);
 	igt_assert_crc_equal(&crc, &rect_2_fb_crc);
-	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
-					  IGT_LOG_WARN), "FBC is not enabled\n");
 
 	/* Clear the second rect as well. Now back to original blank screen */
-	igt_plane_replace_prop_blob(primary, IGT_PLANE_FB_DAMAGE_CLIPS,
-				    &rect2, sizeof(rect2));
-	igt_plane_set_fb(primary, &main_fb);
-	igt_display_commit2(display, COMMIT_ATOMIC);
-	igt_pipe_crc_collect_crc(pipe_crc, &crc);
+	set_damage_area(primary, &rect2, sizeof(rect2));
+	set_fb_and_collect_crc(data, primary, &main_fb, pipe_crc, &crc);
 	igt_assert_crc_equal(&crc, &main_fb_crc);
-	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
-					  IGT_LOG_WARN), "FBC is not enabled\n");
 
 	igt_plane_set_fb(primary, NULL);
 	igt_remove_fb(data->drm_fd, &main_fb);
@@ -225,20 +515,6 @@ static void fbc_dirty_rectangle_complete_set(data_t *data)
 	igt_remove_fb(data->drm_fd, &rect_2_fb);
 	igt_remove_fb(data->drm_fd, &rect_combined_fb);
 	igt_display_commit2(display, COMMIT_ATOMIC);
-	igt_assert_f(intel_fbc_is_enabled(data->drm_fd, data->pipe,
-					  IGT_LOG_WARN), "FBC is not enabled\n");
-
-	if (data->op == FRONTBUFFER) {
-		drmModeClip clip;
-		struct igt_fb fb;
-
-		clip.x1 = clip.y1 = SQUARE_OFFSET;
-		clip.x2 = clip.y2 = SQUARE_OFFSET + SQUARE_SIZE;
-
-		dirty_rect_create_fb(data, &fb, 1, (struct drm_mode_rect *)&clip);
-		ret = drmModeDirtyFB(data->drm_fd, fb.fb_id, &clip, 1);
-		igt_assert(ret == 0);
-	}
 }
 
 static void prepare_test(data_t *data, igt_output_t *output)
@@ -260,6 +536,18 @@ static void fbc_dirty_rectangle_basic(data_t *data)
 	return fbc_dirty_rectangle_complete_set(data);
 }
 
+static void fbc_dirty_rectangle_out_visible(data_t *data)
+{
+	prepare_test(data, NULL);
+	return fbc_dirty_rectangle_outside_visible_region(data);
+}
+
+static void fbc_dirty_rectangle_dirtyfb_tests(data_t *data)
+{
+	prepare_test(data, NULL);
+	return fbc_dirty_rectangle_dirtyfb(data);
+}
+
 igt_main
 {
 	data_t data = {0};
@@ -281,6 +569,7 @@ igt_main
 		for_each_pipe(&data.display, data.pipe) {
 			for_each_valid_output_on_pipe(&data.display, data.pipe, data.output) {
 				data.mode = igt_output_get_mode(data.output);
+				data.format = DRM_FORMAT_XRGB8888;
 				igt_display_reset(&data.display);
 				igt_output_set_pipe(data.output, data.pipe);
 				igt_dynamic_f("%s-%s",
@@ -292,6 +581,42 @@ igt_main
 		}
 	}
 
+	igt_subtest_with_dynamic("fbc-dirty-rectangle-out-visible-area") {
+		data.feature = FEATURE_FBC;
+		igt_require_f(display_ver >= 30, "FBC with dirty region is not supported\n");
+		for_each_pipe(&data.display, data.pipe) {
+			for_each_valid_output_on_pipe(&data.display, data.pipe, data.output) {
+				data.mode = igt_output_get_mode(data.output);
+				data.format = DRM_FORMAT_XRGB8888;
+				igt_display_reset(&data.display);
+				igt_output_set_pipe(data.output, data.pipe);
+				igt_dynamic_f("%s-%s",
+					       kmstest_pipe_name(data.pipe),
+					       igt_output_name(data.output)) {
+					fbc_dirty_rectangle_out_visible(&data);
+				}
+			}
+		}
+	}
+
+	igt_subtest_with_dynamic("fbc-dirty-rectangle-dirtyfb-tests") {
+		data.feature = FEATURE_FBC;
+		igt_require_f(display_ver >= 30, "FBC with dirty region is not supported\n");
+		for_each_pipe(&data.display, data.pipe) {
+			for_each_valid_output_on_pipe(&data.display, data.pipe, data.output) {
+				data.mode = igt_output_get_mode(data.output);
+				data.format = DRM_FORMAT_XRGB8888;
+				igt_display_reset(&data.display);
+				igt_output_set_pipe(data.output, data.pipe);
+				igt_dynamic_f("%s-%s",
+					       kmstest_pipe_name(data.pipe),
+					       igt_output_name(data.output)) {
+					fbc_dirty_rectangle_dirtyfb_tests(&data);
+				}
+			}
+		}
+	}
+
 	igt_subtest_with_dynamic("fbc-dirty-rectangle-different-formats") {
 		uint32_t formats[] = {DRM_FORMAT_XRGB8888,
 				      DRM_FORMAT_ARGB8888,
@@ -320,27 +645,6 @@ igt_main
 		}
 	}
 
-	igt_subtest_with_dynamic("fbc-dirty-rectangle-dirtyfb-ioctl") {
-		data.feature = FEATURE_FBC;
-		igt_require_f(display_ver >= 30, "FBC with dirty region is not supported\n");
-
-		for_each_pipe(&data.display, data.pipe) {
-			for_each_valid_output_on_pipe(&data.display, data.pipe, data.output) {
-				data.mode = igt_output_get_mode(data.output);
-				igt_display_reset(&data.display);
-				igt_output_set_pipe(data.output, data.pipe);
-
-				igt_dynamic_f("%s-%s-dirtyfb-ioctl",
-					       kmstest_pipe_name(data.pipe),
-					       igt_output_name(data.output)) {
-					data.op = FRONTBUFFER;
-					data.format = DRM_FORMAT_XRGB8888;
-					fbc_dirty_rectangle_basic(&data);
-				}
-			}
-		}
-	}
-
 	igt_fixture {
 		igt_display_fini(&data.display);
 		close(data.drm_fd);
-- 
2.43.0



More information about the Intel-gfx-trybot mailing list