minigbm: Add support for CCS Media Compression on MTL
BUG=b:201620358
TEST=null_platform_test -m I915_FORMAT_MOD_4_TILED_MTL_MC_CCS success
cat /sys/kernel/debug/dri/1/i915_display_info during rendering
uapi: [FB:434] XR24 little-endian (0x34325258),0x10000000000000e,1920x1200, visible=visible, src=1920.000000x1200.000000+0.000000+0.000000, dst=1920x1200+0+0, rotation=0 (0x00000001)
hw: [FB:434] XR24 little-endian (0x34325258),0x10000000000000e,1920x1200, visible=yes, src=1920.000000x1200.000000+0.000000+0.000000, dst=1920x1200+0+0, rotation=0 (0x00000001)
[PLANE:47:plane 2A]: type=OVL
and make sure the modifier shows 0x10000000000000e
v3: Rebased the patch as per latest tip and fixes.
Credits-to: Bai, Guangyao <guangyao.bai@intel.com>
Heikkila, Juha-pekka <juha-pekka.heikkila@intel.com>
Ma, Zhaoliang <zhaoliang.ma@intel.com>
Change-Id: I9d9391a2f9b1f8d78f2a70b729f1fcc86b76679d
Signed-off-by: Lobo, Melanie <melanie.lobo@intel.com>
Signed-off-by: Santa, Carlos <carlos.santa@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/5351727
Commit-Queue: Vidya Srinivas <vidya.srinivas@intel.com>
Reviewed-by: Dominik Behr <dbehr@chromium.org>
diff --git a/drv.h b/drv.h
index b61aedf..245fd57 100644
--- a/drv.h
+++ b/drv.h
@@ -98,6 +98,22 @@
#define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS fourcc_mod_code(INTEL, 13)
#endif
+#ifndef I915_FORMAT_MOD_4_TILED_MTL_MC_CCS
+//TODO: remove this defination once drm_fourcc.h contains it.
+/*
+ * Intel color control surfaces (CCS) for display ver 14 media compression
+ *
+ * The main surface is tile4 and at plane index 0, the CCS is linear and
+ * at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in
+ * main surface. In other words, 4 bits in CCS map to a main surface cache
+ * line pair. The main surface pitch is required to be a multiple of four
+ * tile4 widths. For semi-planar formats like NV12, CCS planes follow the
+ * Y and UV planes i.e., planes 0 and 1 are used for Y and UV surfaces,
+ * planes 2 and 3 for the respective CCS.
+ */
+#define I915_FORMAT_MOD_4_TILED_MTL_MC_CCS fourcc_mod_code(INTEL, 14)
+#endif
+
// clang-format on
struct driver;
struct bo;
diff --git a/i915.c b/i915.c
index b9e377f..fd00781 100644
--- a/i915.c
+++ b/i915.c
@@ -46,7 +46,9 @@
DRM_FORMAT_MOD_LINEAR };
static const uint64_t xe_lpdp_modifier_order[] = { I915_FORMAT_MOD_4_TILED_MTL_RC_CCS,
- I915_FORMAT_MOD_4_TILED, I915_FORMAT_MOD_X_TILED,
+ I915_FORMAT_MOD_4_TILED_MTL_MC_CCS,
+ I915_FORMAT_MOD_4_TILED,
+ I915_FORMAT_MOD_X_TILED,
DRM_FORMAT_MOD_LINEAR };
struct modifier_support_t {
@@ -562,7 +564,8 @@
modifier == I915_FORMAT_MOD_4_TILED_MTL_RC_CCS) {
assert(num_planes == 1);
return 2;
- } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) {
+ } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
+ modifier == I915_FORMAT_MOD_4_TILED_MTL_MC_CCS) {
assert(num_planes == 2);
return 4;
}
@@ -570,6 +573,13 @@
return num_planes;
}
+#define gbm_fls(x) ((x) ? __builtin_choose_expr(sizeof(x) == 8, \
+ 64 - __builtin_clzll(x), \
+ 32 - __builtin_clz(x)) : 0)
+
+#define roundup_power_of_two(x) ((x) != 0 ? 1ULL << gbm_fls((x) - 1) : 0)
+
+
static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
uint64_t use_flags, const uint64_t *modifiers, uint32_t count)
{
@@ -590,15 +600,18 @@
* on |use_flags|. Instead the client should request them explicitly through
* gbm_bo_create_with_modifiers().
*/
- assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS);
+ assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS &&
+ modifier != I915_FORMAT_MOD_4_TILED_MTL_MC_CCS);
/* TODO(b/323863689): Account for driver's bandwidth compression in minigbm for
* media compressed buffers. */
}
- if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS &&
- !(format == DRM_FORMAT_NV12 || format == DRM_FORMAT_P010)) {
- drv_loge("Media compression is only supported for NV12 and P010\n");
- return -EINVAL;
- }
+ if ((modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
+ modifier == I915_FORMAT_MOD_4_TILED_MTL_MC_CCS) &&
+ !(format == DRM_FORMAT_NV12 || format == DRM_FORMAT_P010))
+ {
+ drv_loge("Media compression is only supported for NV12 and P010\n");
+ return -EINVAL;
+ }
/*
* i915 only supports linear/x-tiled above 4096 wide on Gen9/Gen10 GPU.
@@ -656,6 +669,7 @@
break;
case I915_FORMAT_MOD_4_TILED:
case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
+ case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
bo->meta.tiling = I915_TILING_4;
break;
}
@@ -782,39 +796,67 @@
/* Total number of planes & sizes */
bo->meta.num_planes = plane + a_plane;
bo->meta.total_size = offset;
- } else if (modifier == I915_FORMAT_MOD_4_TILED_MTL_RC_CCS) {
-
- /*
- * considering only 128 byte compression and one cache line of
- * aux buffer(64B) contains compression status of 4-Y tiles.
- * Which is 4 * (128B * 32L).
- * line stride(bytes) is 4 * 128B
- * and tile stride(lines) is 32L
+ } else if (modifier == I915_FORMAT_MOD_4_TILED_MTL_RC_CCS ||
+ modifier == I915_FORMAT_MOD_4_TILED_MTL_MC_CCS) {
+ /* Media compression modifiers should only be possible via the
+ * gbm_bo_create_with_modifiers() path, i.e., the minigbm client needs to
+ * explicitly request it.
*/
- uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512);
- stride = ALIGN(stride, 256);
+ assert(modifier != I915_FORMAT_MOD_4_TILED_MTL_MC_CCS ||
+ use_flags == BO_USE_NONE);
+ assert(modifier != I915_FORMAT_MOD_4_TILED_MTL_MC_CCS ||
+ bo->meta.use_flags == BO_USE_NONE);
+ assert(modifier != I915_FORMAT_MOD_4_TILED_MTL_MC_CCS ||
+ (!!modifiers && count > 0));
+ assert(modifier != I915_FORMAT_MOD_4_TILED_MTL_MC_CCS ||
+ (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_P010 ||
+ format == DRM_FORMAT_XRGB8888 || format == DRM_FORMAT_XBGR8888));
+ assert(drv_num_planes_from_format(format) > 0);
- height = ALIGN(drv_height_from_format(format, height, 0), 32);
+ uint32_t offset = 0, stride = 0;
+ size_t plane = 0;
+ size_t a_plane = 0;
+ for(plane = 0; plane < drv_num_planes_from_format(format); plane++) {
+ uint32_t alignment = 0, val, tmpoffset = 0;
+ /*
+ * tile_align = 4 (for width) for CCS and
+ * tile_width = 128, tile_height = 32 for MC CCS
+ */
+ stride = ALIGN(drv_stride_from_format(format, width, plane), 512);
+ height = ALIGN(drv_height_from_format(format, height, plane), 32);
+ bo->meta.strides[plane] = stride;
- bo->meta.strides[0] = stride;
- /* size calculation and alignment are 64KB aligned
- * size as per spec
- */
- bo->meta.sizes[0] = ALIGN(stride * height, 65536);
- bo->meta.offsets[0] = 0;
+ /* MTL needs 1MB Alignment */
+ bo->meta.sizes[plane] = ALIGN(stride * height, 0x100000);
+ if (plane == 1 && (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_P010)) {
+ alignment = 1 << 20;
+ offset += alignment - (offset % alignment);
+ tmpoffset = offset;
+ val = roundup_power_of_two(stride);
+ if ((stride * val) > tmpoffset)
+ offset = stride * val;
+ }
+
+ bo->meta.offsets[plane] = offset;
+ offset += bo->meta.sizes[plane];
+ }
/* Aux buffer is linear and page aligned. It is placed after
* other planes and aligned to main buffer stride.
*/
- bo->meta.strides[1] = bo->meta.strides[0] / 8;
+ for(a_plane = 0; a_plane < plane; a_plane++) {
+ stride = bo->meta.strides[a_plane] / 8;
+ bo->meta.strides[a_plane + plane] = stride;
- /* Aligned to page size */
- bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize());
- bo->meta.offsets[1] = bo->meta.sizes[0];
- /* Total number of planes & sizes */
- bo->meta.num_planes = 2;
- bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
+ /* Aligned to page size */
+ bo->meta.sizes[a_plane + plane] = ALIGN(bo->meta.sizes[a_plane] / 256, getpagesize());
+ bo->meta.offsets[a_plane + plane] = offset;
+ /* next buffer offset */
+ offset += bo->meta.sizes[plane + a_plane];
+ }
+ bo->meta.num_planes = a_plane + plane;
+ bo->meta.total_size = offset;
} else {
return i915_bo_from_format(bo, width, height, format);
}
@@ -933,7 +975,8 @@
(bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) ||
(bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) ||
(bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED) ||
- (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED_MTL_RC_CCS))
+ (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED_MTL_RC_CCS) ||
+ (bo->meta.format_modifier == I915_FORMAT_MOD_4_TILED_MTL_MC_CCS))
return MAP_FAILED;
if (bo->meta.tiling == I915_TILING_NONE) {