[igt-dev] [PATCH i-g-t 2/3] lib/igt_fb: switch blitcopy to use lib/i915/i915_blt functions

Juha-Pekka Heikkila juhapekka.heikkila at gmail.com
Tue Mar 28 18:30:42 UTC 2023


reduce code duplication

Signed-off-by: Juha-Pekka Heikkila <juhapekka.heikkila at gmail.com>
---
 lib/igt_fb.c | 214 +++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 191 insertions(+), 23 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index ba89e1f60..7668fc553 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -35,6 +35,8 @@
 #include "drmtest.h"
 #include "i915/gem_create.h"
 #include "i915/gem_mman.h"
+#include "i915/i915_blt.h"
+#include "i915/intel_mocs.h"
 #include "igt_aux.h"
 #include "igt_color_encoding.h"
 #include "igt_fb.h"
@@ -2680,12 +2682,132 @@ static void copy_with_engine(struct fb_blit_upload *blit,
 	fini_buf(src);
 }
 
+static struct blt_copy_object *blt_fb_init(const struct igt_fb *fb,
+					   uint32_t plane, uint32_t memregion)
+{
+	uint32_t name, handle;
+	struct blt_copy_object *blt;
+	enum blt_tiling_type blt_tile;
+	uint64_t stride;
+
+	blt = malloc(sizeof(*blt));
+	igt_assert(blt);
+
+	name = gem_flink(fb->fd, fb->gem_handle);
+	handle = gem_open(fb->fd, name);
+
+	switch (igt_fb_mod_to_tiling(fb->modifier)) {
+	case I915_TILING_X:
+		blt_tile = T_XMAJOR;
+		stride = fb->strides[plane] / 4;
+		break;
+	case I915_TILING_Y:
+		blt_tile = T_YMAJOR;
+		stride = fb->strides[plane] / 4;
+		break;
+	case I915_TILING_4:
+		blt_tile = T_TILE4;
+		stride = fb->strides[plane] / 4;
+		break;
+	case I915_TILING_NONE:
+	default:
+		blt_tile = T_LINEAR;
+		stride = fb->strides[plane];
+		break;
+	}
+
+	blt_set_object(blt, handle, fb->size, memregion,
+		       intel_get_uc_mocs(fb->fd),
+		       blt_tile,
+		       is_ccs_modifier(fb->modifier) ? COMPRESSION_ENABLED : COMPRESSION_DISABLED,
+		       is_gen12_mc_ccs_modifier(fb->modifier) ? COMPRESSION_TYPE_MEDIA : COMPRESSION_TYPE_3D);
+
+	blt_set_geom(blt, stride, 0, 0, fb->width, fb->plane_height[plane], 0, 0);
+
+	blt->offset = fb->offsets[plane];
+
+	blt->ptr = gem_mmap__device_coherent(fb->fd, handle, 0, fb->size,
+					     PROT_READ | PROT_WRITE);
+	return blt;
+}
+
+static enum blt_color_depth blt_get_bpp(const struct igt_fb *fb)
+{
+	switch (fb->plane_bpp[0]) {
+	case 8:
+		return CD_8bit;
+	case 16:
+		return CD_16bit;
+	case 32:
+		return CD_32bit;
+	case 64:
+		return CD_64bit;
+	case 96:
+		return CD_96bit;
+	case 128:
+		return CD_128bit;
+	default:
+		igt_assert(0);
+	}
+}
+
+#define BLT_TARGET_RC(x) (x.compression == COMPRESSION_ENABLED && \
+			  x.compression_type == COMPRESSION_TYPE_3D)
+
+#define BLT_TARGET_MC(x) (x.compression == COMPRESSION_ENABLED && \
+			  x.compression_type == COMPRESSION_TYPE_MEDIA)
+
+static uint32_t blt_compression_format(struct blt_copy_data *blt,
+				       const struct igt_fb *fb)
+{
+	if (blt->src.compression == COMPRESSION_DISABLED &&
+	    blt->dst.compression == COMPRESSION_DISABLED)
+		return 0;
+
+	if (BLT_TARGET_RC(blt->src) || BLT_TARGET_RC(blt->dst)) {
+		switch (blt->color_depth) {
+		case CD_32bit:
+			return 8;
+		default:
+			igt_assert_f(0, "COMPRESSION_TYPE_3D unknown color depth\n");
+		}
+	}
+
+	if (BLT_TARGET_MC(blt->src) || BLT_TARGET_MC(blt->dst)) {
+		switch (fb->drm_format) {
+		case DRM_FORMAT_XRGB8888:
+			return 8;
+		case DRM_FORMAT_XYUV8888:
+			return 9;
+		case DRM_FORMAT_NV12:
+			return 9;
+		case DRM_FORMAT_P010:
+		case DRM_FORMAT_P012:
+		case DRM_FORMAT_P016:
+			return 8;
+		default:
+			igt_assert_f(0, "COMPRESSION_TYPE_MEDIA unknown format\n");
+		}
+	} else {
+		igt_assert_f(0, "unknown compression\n");
+	}
+}
+
 static void blitcopy(const struct igt_fb *dst_fb,
 		     const struct igt_fb *src_fb)
 {
 	uint32_t src_tiling, dst_tiling;
 	uint32_t ctx = 0;
 	uint64_t ahnd = 0;
+	const intel_ctx_t *ictx = intel_ctx_create_all_physical(src_fb->fd);
+	struct intel_execution_engine2 *e;
+	uint32_t bb;
+	uint64_t bb_size = 4096;
+	struct blt_copy_data blt = {};
+	struct blt_copy_object *src, *dst;
+	struct blt_block_copy_data_ext ext = {}, *pext = NULL;
+	uint32_t mem_region = HAS_FLATCCS(intel_get_drm_devid(src_fb->fd))
+			   ? REGION_LMEM(0) : REGION_SMEM;
 
 	igt_assert_eq(dst_fb->fd, src_fb->fd);
 	igt_assert_eq(dst_fb->num_planes, src_fb->num_planes);
@@ -2697,36 +2819,81 @@ static void blitcopy(const struct igt_fb *dst_fb,
 		igt_require(gem_has_contexts(dst_fb->fd));
 		ctx = gem_context_create(dst_fb->fd);
 		ahnd = get_reloc_ahnd(dst_fb->fd, ctx);
+
+		igt_assert(__gem_create_in_memory_regions(src_fb->fd,
+							  &bb,
+							  &bb_size,
+							  mem_region) == 0);
+
+		for_each_ctx_engine(src_fb->fd, ictx, e) {
+			if (gem_engine_can_block_copy(src_fb->fd, e))
+				break;
+		}
 	}
 
 	for (int i = 0; i < dst_fb->num_planes; i++) {
 		igt_assert_eq(dst_fb->plane_bpp[i], src_fb->plane_bpp[i]);
 		igt_assert_eq(dst_fb->plane_width[i], src_fb->plane_width[i]);
 		igt_assert_eq(dst_fb->plane_height[i], src_fb->plane_height[i]);
-		/*
-		 * On GEN12+ X-tiled format support is removed from the fast
-		 * blit command, so use the XY_SRC blit command for it
-		 * instead.
-		 */
-		if (fast_blit_ok(src_fb) && fast_blit_ok(dst_fb)) {
-			igt_blitter_fast_copy__raw(dst_fb->fd,
-						   ahnd, ctx, NULL,
-						   src_fb->gem_handle,
-						   src_fb->offsets[i],
-						   src_fb->strides[i],
-						   src_tiling,
-						   0, 0, /* src_x, src_y */
-						   src_fb->size,
-						   dst_fb->plane_width[i],
-						   dst_fb->plane_height[i],
-						   dst_fb->plane_bpp[i],
-						   dst_fb->gem_handle,
-						   dst_fb->offsets[i],
-						   dst_fb->strides[i],
-						   dst_tiling,
-						   0, 0 /* dst_x, dst_y */,
-						   dst_fb->size);
+
+		if (ahnd && fast_blit_ok(src_fb) && fast_blit_ok(dst_fb)) {
+			memset(&blt, 0, sizeof(blt));
+			blt.color_depth = blt_get_bpp(src_fb);
+
+			src = blt_fb_init(src_fb, i, mem_region);
+			dst = blt_fb_init(dst_fb, i, mem_region);
+
+			blt_set_copy_object(&blt.src, src);
+			blt_set_copy_object(&blt.dst, dst);
+
+			blt_set_batch(&blt.bb, bb, bb_size, mem_region);
+
+			blt_fast_copy(src_fb->fd, ictx, e, ahnd, &blt);
+			gem_sync(src_fb->fd, blt.dst.handle);
+
+			blt_destroy_object(src_fb->fd, src);
+			blt_destroy_object(dst_fb->fd, dst);
+		} else if (ahnd && blt_has_block_copy(src_fb->fd)) {
+			/*
+			* On GEN12+ X-tiled format support is removed from
+			* the fast blit command, so use the block copy blit
+			* command for it instead.
+			*/
+			src = blt_fb_init(src_fb, i, mem_region);
+			dst = blt_fb_init(dst_fb, i, mem_region);
+
+			memset(&blt, 0, sizeof(blt));
+			blt.print_bb = true;
+			blt.color_depth = blt_get_bpp(src_fb);
+			blt_set_copy_object(&blt.src, src);
+			blt_set_copy_object(&blt.dst, dst);
+
+			if (HAS_FLATCCS(intel_get_drm_devid(src_fb->fd))) {
+				blt_set_object_ext(&ext.src,
+						   blt_compression_format(&blt, src_fb),
+						   src_fb->width, src_fb->height,
+						   SURFACE_TYPE_2D);
+
+				blt_set_object_ext(&ext.dst,
+						   blt_compression_format(&blt, dst_fb),
+						   dst_fb->width, dst_fb->height,
+						   SURFACE_TYPE_2D);
+
+				pext = &ext;
+			}
+
+			blt_set_batch(&blt.bb, bb, bb_size, mem_region);
+
+			blt_block_copy(src_fb->fd, ictx, e, ahnd, &blt, pext);
+			gem_sync(src_fb->fd, blt.dst.handle);
+
+			blt_destroy_object(src_fb->fd, src);
+			blt_destroy_object(dst_fb->fd, dst);
 		} else {
+			/*
+			 * If on legacy hardware where relocations are supported
+			 * we'll use XY_SRC blit command instead
+			 */
 			igt_blitter_src_copy(dst_fb->fd,
 					     ahnd, ctx, NULL,
 					     src_fb->gem_handle,
@@ -2750,6 +2917,7 @@ static void blitcopy(const struct igt_fb *dst_fb,
 	if (ctx)
 		gem_context_destroy(dst_fb->fd, ctx);
 	put_ahnd(ahnd);
+	intel_ctx_destroy(src_fb->fd, ictx);
 }
 
 static void free_linear_mapping(struct fb_blit_upload *blit)
-- 
2.39.0



More information about the igt-dev mailing list