summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHang Nguyen <hnt@google.com>2023-06-28 21:47:59 +0000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-09-15 16:31:12 +0000
commitbb30e856312fb239b5a6cb4c4ec77a578ca61c25 (patch)
treefa6403b8ffbe4eb67cf88c50112be3f4d271169e
parent0bf79720e80b05e97c3aa01c9a9b069d98f82bc8 (diff)
downloadminigbm-bb30e856312fb239b5a6cb4c4ec77a578ca61c25.tar.gz
i915: Add media compression support for Gen-12 with feature flag
From Gen-12 onwards Media compression aux buffer layout has been changed. The functionality to allocate minigbm compressed buffers are mostly taken from CL:3275292 and this CL adapts it to guard this feature behind an environment variable controlled by the minigbm user application (we're not re-using the original CL because it seems the original author is no longer active). BUG=b:201620358 TEST=Play video on Chrome with feature flag enabled for MMC and verify type (7) of buffer modifer in the output of below command: localhost ~ # cat /sys/kernel/debug/dri/0/i915_gem_framebuffer user size: 1280 x 720, depth 0, 8 bpp, modifier 0x100000000000007 Change-Id: I69cb527eb9d16498f7e9c2fb32c793cea6b6a4ed Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/4655427 Reviewed-by: Andres Calderon Jaramillo <andrescj@google.com> Commit-Queue: Hang Nguyen <hnt@chromium.org> Tested-by: Hang Nguyen <hnt@chromium.org>
-rw-r--r--i915.c126
1 files changed, 99 insertions, 27 deletions
diff --git a/i915.c b/i915.c
index 7027429..dac45cb 100644
--- a/i915.c
+++ b/i915.c
@@ -37,9 +37,16 @@ static const uint32_t texture_only_formats[] = { DRM_FORMAT_R8, DRM_FORMAT_NV12,
static const uint64_t gen_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED,
I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR };
-static const uint64_t gen12_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
- I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
- DRM_FORMAT_MOD_LINEAR };
+static const uint64_t gen12_modifier_order_without_mc[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
+ I915_FORMAT_MOD_Y_TILED,
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR };
+
+static const uint64_t gen12_modifier_order_with_mc[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
+ I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
+ I915_FORMAT_MOD_Y_TILED,
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR };
static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
DRM_FORMAT_MOD_LINEAR };
@@ -63,6 +70,7 @@ struct i915_device {
bool is_mtl;
int32_t num_fences_avail;
bool has_mmap_offset;
+ bool is_media_compression_enabled;
};
static void i915_info_from_device_id(struct i915_device *i915)
@@ -192,8 +200,13 @@ static void i915_get_modifier_order(struct i915_device *i915)
i915->modifier.order = xe_lpdp_modifier_order;
i915->modifier.count = ARRAY_SIZE(xe_lpdp_modifier_order);
} else if (i915->graphics_version == 12) {
- i915->modifier.order = gen12_modifier_order;
- i915->modifier.count = ARRAY_SIZE(gen12_modifier_order);
+ if (i915->is_media_compression_enabled) {
+ i915->modifier.order = gen12_modifier_order_with_mc;
+ i915->modifier.count = ARRAY_SIZE(gen12_modifier_order_with_mc);
+ } else {
+ i915->modifier.order = gen12_modifier_order_without_mc;
+ i915->modifier.count = ARRAY_SIZE(gen12_modifier_order_without_mc);
+ }
} else if (i915->graphics_version == 11) {
i915->modifier.order = gen11_modifier_order;
i915->modifier.count = ARRAY_SIZE(gen11_modifier_order);
@@ -295,9 +308,14 @@ static int i915_add_combinations(struct driver *drv)
ARRAY_SIZE(scanout_render_formats), &metadata_4_tiled,
scanout_and_render_not_linear);
} else {
- struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y,
- .priority = 3,
- .modifier = I915_FORMAT_MOD_Y_TILED };
+ struct format_metadata metadata_y_tiled = {
+ .tiling = I915_TILING_Y,
+ .priority = 3,
+ .modifier =
+ (i915->graphics_version == 12 && i915->is_media_compression_enabled)
+ ? I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS
+ : I915_FORMAT_MOD_Y_TILED
+ };
/* Support y-tiled NV12 and P010 for libva */
#ifdef I915_SCANOUT_Y_TILED
const uint64_t nv12_usage =
@@ -311,6 +329,11 @@ static int i915_add_combinations(struct driver *drv)
#endif
drv_add_combination(drv, DRM_FORMAT_NV12, &metadata_y_tiled, nv12_usage);
drv_add_combination(drv, DRM_FORMAT_P010, &metadata_y_tiled, p010_usage);
+
+ /* Don't allocate media compressed buffers for formats other than NV12
+ * and P010.
+ */
+ metadata_y_tiled.modifier = I915_FORMAT_MOD_Y_TILED;
drv_add_combinations(drv, render_formats, ARRAY_SIZE(render_formats),
&metadata_y_tiled, render_not_linear);
/* Y-tiled scanout isn't available on old platforms so we add
@@ -436,6 +459,17 @@ static int i915_init(struct driver *drv)
if (!i915)
return -ENOMEM;
+ const char *enable_intel_media_compression_env_var =
+ getenv("ENABLE_INTEL_MEDIA_COMPRESSION");
+ if (enable_intel_media_compression_env_var == NULL) {
+ drv_logd("Failed to get ENABLE_INTEL_MEDIA_COMPRESSION");
+ i915->is_media_compression_enabled = false;
+ } else {
+ i915->is_media_compression_enabled =
+ (drv->compression) &&
+ (strcmp(enable_intel_media_compression_env_var, "1") == 0);
+ }
+
get_param.param = I915_PARAM_CHIPSET_ID;
get_param.value = &(i915->device_id);
ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
@@ -553,6 +587,13 @@ static size_t i915_num_planes_from_modifier(struct driver *drv, uint32_t format,
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
assert(num_planes == 1);
return 2;
+ } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) {
+ assert(drv);
+ struct i915_device *i915 = drv->priv;
+ assert(i915 && i915->is_media_compression_enabled);
+
+ assert(num_planes == 2);
+ return 4;
}
return num_planes;
@@ -613,6 +654,9 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
modifier = DRM_FORMAT_MOD_LINEAR;
}
+ assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
+ i915->is_media_compression_enabled);
+
switch (modifier) {
case DRM_FORMAT_MOD_LINEAR:
bo->meta.tiling = I915_TILING_NONE;
@@ -626,6 +670,7 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
* IPs(render/media/display)
*/
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
+ case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
bo->meta.tiling = I915_TILING_Y;
break;
case I915_FORMAT_MOD_4_TILED:
@@ -687,8 +732,17 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
bo->meta.total_size = offset;
- } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
+ } else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
+ modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) {
+ assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
+ i915->is_media_compression_enabled);
+ assert(modifier != I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
+ (format == DRM_FORMAT_NV12 || format == DRM_FORMAT_P010));
+ assert(drv_num_planes_from_format(format) > 0);
+ uint32_t offset = 0;
+ size_t plane = 0;
+ size_t a_plane = 0;
/*
* considering only 128 byte compression and one cache line of
* aux buffer(64B) contains compression status of 4-Y tiles.
@@ -696,32 +750,49 @@ static int i915_bo_compute_metadata(struct bo *bo, uint32_t width, uint32_t heig
* line stride(bytes) is 4 * 128B
* and tile stride(lines) is 32L
*/
- uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512);
+ for (plane = 0; plane < drv_num_planes_from_format(format); plane++) {
+ uint32_t stride = ALIGN(drv_stride_from_format(format, width, plane), 512);
- height = ALIGN(drv_height_from_format(format, height, 0), 32);
+ const uint32_t plane_height = drv_height_from_format(format, height, plane);
+ uint32_t aligned_height = ALIGN(plane_height, 32);
- if (i915->is_xelpd && (stride > 1)) {
- stride = 1 << (32 - __builtin_clz(stride - 1));
- height = ALIGN(drv_height_from_format(format, height, 0), 128);
- }
+ if (i915->is_xelpd && (stride > 1)) {
+ stride = 1 << (32 - __builtin_clz(stride - 1));
+ aligned_height = ALIGN(plane_height, 128);
+ }
- 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;
+ bo->meta.strides[plane] = stride;
+ /* size calculation & alignment are 64KB aligned
+ * size as per spec
+ */
+ bo->meta.sizes[plane] = ALIGN(stride * aligned_height, 512 * 128);
+ bo->meta.offsets[plane] = offset;
+ /* next buffer 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;
- /* Aligned to page size */
- bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize());
- bo->meta.offsets[1] = bo->meta.sizes[0];
+ for (a_plane = 0; a_plane < plane; a_plane++) {
+ /* Every 64 bytes in the aux plane contain compression information for a
+ * sub-row of 4 Y tiles of the corresponding main plane, so the pitch in
+ * bytes of the aux plane should be the pitch of the main plane in units of
+ * 4 tiles multiplied by 64 (or equivalently, the pitch of the main plane in
+ * bytes divided by 8).
+ */
+ bo->meta.strides[plane + a_plane] = bo->meta.strides[a_plane] / 8;
+ /* Aligned to page size */
+ bo->meta.sizes[plane + a_plane] =
+ ALIGN(bo->meta.sizes[a_plane] / 256, 4 * 1024);
+ bo->meta.offsets[plane + a_plane] = offset;
+
+ /* next buffer offset */
+ offset += bo->meta.sizes[plane + a_plane];
+ }
/* Total number of planes & sizes */
- bo->meta.num_planes = i915_num_planes_from_modifier(bo->drv, format, modifier);
- bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
+ bo->meta.num_planes = plane + a_plane;
+ bo->meta.total_size = offset;
} else {
return i915_bo_from_format(bo, width, height, format);
}
@@ -834,6 +905,7 @@ static void *i915_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
if ((bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS) ||
(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))
return MAP_FAILED;