Merge upstream-main into main am: 018f7ff8fa am: d7bbfc10d3

Original change: https://android-review.googlesource.com/c/platform/external/minigbm/+/3149096

Change-Id: I0c2e233dce128631c480bdb287e0c09add56ac94
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/Makefile b/Makefile
index db27cf6..90805dd 100644
--- a/Makefile
+++ b/Makefile
@@ -42,14 +42,16 @@
 CPPFLAGS += $(PC_CFLAGS)
 LDLIBS += $(PC_LIBS)
 
-LIBDIR ?= /usr/lib/
+DESTDIR ?= $(OUT)/install
+LIBDIR ?= /usr/lib
+INCLUDEDIR ?= /usr/include
 
-GBM_VERSION_MAJOR := 1
-MINIGBM_VERSION := $(GBM_VERSION_MAJOR).0.0
+MINIGBM_VERSION_MAJOR := 1
+MINIGBM_VERSION := $(MINIGBM_VERSION_MAJOR).0.0
 MINIGBM_FILENAME := libminigbm.so.$(MINIGBM_VERSION)
 
-CC_LIBRARY($(MINIGBM_FILENAME)): LDFLAGS += -Wl,-soname,libgbm.so.$(GBM_VERSION_MAJOR)
-CC_LIBRARY($(MINIGBM_FILENAME)): $(C_OBJECTS)
+CC_LIBRARY($(MINIGBM_FILENAME)): LDFLAGS += -Wl,-soname,libgbm.so.$(MINIGBM_VERSION_MAJOR)
+CC_LIBRARY($(MINIGBM_FILENAME)): $(C_OBJECTS) pkgconfig
 CC_STATIC_LIBRARY(libminigbm.pie.a): $(C_OBJECTS)
 
 all: CC_LIBRARY($(MINIGBM_FILENAME))
@@ -63,11 +65,33 @@
 clean: CLEAN(gbm_unittest)
 tests: TEST(CXX_BINARY(gbm_unittest))
 
+define pkgconfig_contents
+prefix=$(DESTDIR)
+exec_prefix=$${prefix}
+includedir=$${prefix}/$(INCLUDEDIR)
+libdir=$${prefix}/$(LIBDIR)
+
+Name: libgbm
+Description: A small gbm implementation
+Version: 18.0.0
+Cflags: -I$${includedir}
+Libs: -L$${libdir} -lgbm
+Requires.private: libdrm >= 2.4.50
+endef
+
+.PHONY: pkgconfig
+pkgconfig:
+	@echo "generating $(OUT)gbm.pc"
+	$(file > $(OUT)/gbm.pc,$(pkgconfig_contents))
+clean:
+	rm -f $(OUT)gbm.pc
+
 install: all
 	mkdir -p $(DESTDIR)/$(LIBDIR)
 	install -D -m 755 $(OUT)/$(MINIGBM_FILENAME) $(DESTDIR)/$(LIBDIR)
 	ln -sf $(MINIGBM_FILENAME) $(DESTDIR)/$(LIBDIR)/libgbm.so
-	ln -sf $(MINIGBM_FILENAME) $(DESTDIR)/$(LIBDIR)/libgbm.so.$(GBM_VERSION_MAJOR)
-	install -D -m 0644 $(SRC)/gbm.pc $(DESTDIR)$(LIBDIR)/pkgconfig/gbm.pc
-	install -D -m 0644 $(SRC)/gbm.h $(DESTDIR)/usr/include/gbm.h
-	install -D -m 0644 $(SRC)/minigbm_helpers.h $(DESTDIR)/usr/include/minigbm/minigbm_helpers.h
+	ln -sf $(MINIGBM_FILENAME) $(DESTDIR)/$(LIBDIR)/libgbm.so.$(MINIGBM_VERSION_MAJOR)
+	ln -sf $(MINIGBM_FILENAME) $(DESTDIR)/$(LIBDIR)/libgbm.so.$(MINIGBM_VERSION)
+	install -D -m 0644 $(OUT)/gbm.pc $(DESTDIR)/$(LIBDIR)/pkgconfig/gbm.pc
+	install -D -m 0644 $(SRC)/gbm.h $(DESTDIR)/$(INCLUDEDIR)/gbm.h
+	install -D -m 0644 $(SRC)/minigbm_helpers.h $(DESTDIR)/$(INCLUDEDIR)/minigbm/minigbm_helpers.h
diff --git a/OWNERS b/OWNERS
index e47b7b8..e03c24d 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,20 +1,21 @@
 [email protected]
[email protected]
 [email protected]
 [email protected]
 [email protected]
 [email protected]
[email protected]
 [email protected]
 [email protected]
[email protected]
 [email protected]
 [email protected]
 [email protected]
 [email protected]
 
 # just reference for backend specific reviews
-per-file amdgpu.c = [email protected], [email protected]
-per-file i915.c = [email protected], [email protected], [email protected]
-per-file mediatek.c = [email protected], [email protected], [email protected]
-per-file msm.c = [email protected], [email protected]
+per-file amdgpu.c = [email protected], [email protected], [email protected]
+per-file i915.c = [email protected], [email protected]
+per-file mediatek.c = [email protected], [email protected]
+per-file msm.c = [email protected]
 per-file rockchip.c = [email protected]
-per-file virtgpu* = [email protected], [email protected], [email protected], [email protected]
+per-file virtgpu* = [email protected], [email protected], [email protected]
diff --git a/backend_mock.c b/backend_mock.c
index ae0d758..67012ad 100644
--- a/backend_mock.c
+++ b/backend_mock.c
@@ -6,7 +6,8 @@
 
 #include "drv_priv.h"
 
-static int backend_mock_init(struct driver *drv) {
+static int backend_mock_init(struct driver *drv)
+{
 	return 0;
 }
 
diff --git a/cros_gralloc/cros_gralloc_helpers.cc b/cros_gralloc/cros_gralloc_helpers.cc
index 67a53a0..4b40bfd 100644
--- a/cros_gralloc/cros_gralloc_helpers.cc
+++ b/cros_gralloc/cros_gralloc_helpers.cc
@@ -78,6 +78,16 @@
 	case HAL_PIXEL_FORMAT_YCBCR_P010:
 		return DRM_FORMAT_P010;
 #endif
+	case HAL_PIXEL_FORMAT_DEPTH_16:
+		return DRM_FORMAT_DEPTH16;
+	case HAL_PIXEL_FORMAT_DEPTH_24:
+		return DRM_FORMAT_DEPTH24;
+	case HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
+		return DRM_FORMAT_DEPTH24_STENCIL8;
+	case HAL_PIXEL_FORMAT_DEPTH_32F:
+		return DRM_FORMAT_DEPTH32;
+	case HAL_PIXEL_FORMAT_DEPTH_32F_STENCIL_8:
+		return DRM_FORMAT_DEPTH32_STENCIL8;
 	}
 
 	return DRM_FORMAT_NONE;
diff --git a/cros_gralloc/gralloc0/tests/gralloctest.c b/cros_gralloc/gralloc0/tests/gralloctest.c
index 9d8101c..1641b8a 100644
--- a/cros_gralloc/gralloc0/tests/gralloctest.c
+++ b/cros_gralloc/gralloc0/tests/gralloctest.c
@@ -22,7 +22,7 @@
 #include <sync/sync.h>
 #include <system/graphics.h>
 
-#define ALIGN(A, B) (((A) + (B)-1) / (B) * (B))
+#define ALIGN(A, B) (((A) + (B) - 1) / (B) * (B))
 #define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))
 
 #define CHECK(cond)                                                                                \
diff --git a/drv.c b/drv.c
index ea3bd64..7fd2250 100644
--- a/drv.c
+++ b/drv.c
@@ -121,7 +121,8 @@
 
 	const char *minigbm_debug;
 	minigbm_debug = drv_get_os_option(MINIGBM_DEBUG);
-	drv->compression = (minigbm_debug == NULL) || (strstr(minigbm_debug, "nocompression") == NULL);
+	drv->compression =
+	    (minigbm_debug == NULL) || (strstr(minigbm_debug, "nocompression") == NULL);
 	drv->log_bos = (minigbm_debug && strstr(minigbm_debug, "log_bos") != NULL);
 
 	drv->fd = fd;
@@ -732,19 +733,15 @@
 {
 	const struct bo_metadata *meta = &bo->meta;
 
-	drv_logd("%s %s bo %p: %dx%d '%c%c%c%c' tiling %d plane %zu mod 0x%" PRIx64 " use 0x%" PRIx64 " size %zu\n",
-		 prefix, bo->drv->backend->name, bo,
-		 meta->width, meta->height,
-		 meta->format & 0xff,
-		 (meta->format >> 8) & 0xff,
-		 (meta->format >> 16) & 0xff,
-		 (meta->format >> 24) & 0xff,
-		 meta->tiling, meta->num_planes, meta->format_modifier,
+	drv_logd("%s %s bo %p: %dx%d '%c%c%c%c' tiling %d plane %zu mod 0x%" PRIx64
+		 " use 0x%" PRIx64 " size %zu\n",
+		 prefix, bo->drv->backend->name, bo, meta->width, meta->height, meta->format & 0xff,
+		 (meta->format >> 8) & 0xff, (meta->format >> 16) & 0xff,
+		 (meta->format >> 24) & 0xff, meta->tiling, meta->num_planes, meta->format_modifier,
 		 meta->use_flags, meta->total_size);
 	for (uint32_t i = 0; i < meta->num_planes; i++) {
-		drv_logd("  bo %p plane %d: offset %d size %d stride %d\n",
-			 bo, i, meta->offsets[i], meta->sizes[i],
-			 meta->strides[i]);
+		drv_logd("  bo %p plane %d: offset %d size %d stride %d\n", bo, i, meta->offsets[i],
+			 meta->sizes[i], meta->strides[i]);
 	}
 }
 
diff --git a/drv.h b/drv.h
index b61aedf..bd380b5 100644
--- a/drv.h
+++ b/drv.h
@@ -64,6 +64,14 @@
 #define DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED	fourcc_code('9', '9', '9', '8')
 #define DRM_FORMAT_FLEX_YCbCr_420_888		fourcc_code('9', '9', '9', '9')
 
+#ifndef DRM_FORMAT_DEPTH16
+#define DRM_FORMAT_DEPTH16 fourcc_code('D', '1', '6', ' ')
+#define DRM_FORMAT_DEPTH24 fourcc_code('D', '2', '4', 'X')
+#define DRM_FORMAT_DEPTH24_STENCIL8 fourcc_code('D', '2', '4', 'S')
+#define DRM_FORMAT_DEPTH32 fourcc_code('D', '3', '2', 'F')
+#define DRM_FORMAT_DEPTH32_STENCIL8 fourcc_code('D', 'F', 'S', '8')
+#endif
+
 /* This is a 10-bit bayer format for private reprocessing on MediaTek ISP. It's
  * a private RAW format that other DRM drivers will never support and thus
  * making it not upstreamable (i.e., defined in official DRM headers). */
@@ -98,6 +106,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/drv_helpers.c b/drv_helpers.c
index c810d8e..12b671a 100644
--- a/drv_helpers.c
+++ b/drv_helpers.c
@@ -100,6 +100,7 @@
 		return &packed_1bpp_layout;
 
 	case DRM_FORMAT_R16:
+	case DRM_FORMAT_DEPTH16:
 		return &packed_2bpp_layout;
 
 	case DRM_FORMAT_YVU420:
@@ -144,6 +145,9 @@
 	case DRM_FORMAT_RGB888:
 		return &packed_3bpp_layout;
 
+	case DRM_FORMAT_DEPTH24:
+	case DRM_FORMAT_DEPTH24_STENCIL8:
+	case DRM_FORMAT_DEPTH32:
 	case DRM_FORMAT_ABGR2101010:
 	case DRM_FORMAT_ABGR8888:
 	case DRM_FORMAT_ARGB2101010:
@@ -163,6 +167,7 @@
 	case DRM_FORMAT_XRGB8888:
 		return &packed_4bpp_layout;
 
+	case DRM_FORMAT_DEPTH32_STENCIL8:
 	case DRM_FORMAT_ABGR16161616F:
 		return &packed_8bpp_layout;
 
diff --git a/gbm.h b/gbm.h
index 8e32769..197324c 100644
--- a/gbm.h
+++ b/gbm.h
@@ -413,6 +413,18 @@
            uint32_t x, uint32_t y, uint32_t width, uint32_t height,
            uint32_t flags, uint32_t *stride, void **map_data);
 
+/* Neither gbm_bo_map_cache_mode nor gbm_bo_get_map_info are defined in mesa's gbm.h, or older
+ * versions of minigbm. For backwards-compatibility, users should first test for availability and
+ * provide a fallback implementation with:
+ *
+ *   #if defined(MINIGBM) && defined(MINIGBM_HAS_GBM_BO_GET_MAP_INFO)
+ *   // use gbm_bo_get_map_info()
+ *   #else
+ *   // fallback
+ *   #endif
+ */
+#define MINIGBM_HAS_GBM_BO_GET_MAP_INFO
+
 /**
  * Enum to indicate the cache attributes of CPU mapping returned by
  * gbm_bo_map()
diff --git a/gbm.pc b/gbm.pc
deleted file mode 100644
index a7509fc..0000000
--- a/gbm.pc
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=/usr
-exec_prefix=${prefix}
-includedir=${prefix}/include
-libdir=${exec_prefix}/lib
-
-Name: libgbm
-Description: A small gbm implementation
-Version: 18.0.0
-Cflags: -I${includedir}
-Libs: -L${libdir} -lgbm
diff --git a/gbm_unittest.cc b/gbm_unittest.cc
index 9f2a46f..bad568f 100644
--- a/gbm_unittest.cc
+++ b/gbm_unittest.cc
@@ -14,7 +14,7 @@
 
 class MockDrm
 {
- public:
+      public:
 	MOCK_METHOD(drmVersionPtr, drmGetVersion, (int fd));
 	MOCK_METHOD(void, drmFreeVersion, (drmVersionPtr v));
 };
@@ -30,7 +30,7 @@
 // Define a mock version of drmFreeVersion
 void drmFreeVersion(drmVersionPtr v)
 {
-	delete(v);
+	delete (v);
 }
 
 /* TODO : This is a protocol to add unit tests for the public APIs in minigbm.
diff --git a/i915.c b/i915.c
index b9e377f..f9b79b1 100644
--- a/i915.c
+++ b/i915.c
@@ -37,15 +37,16 @@
 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_GEN12_MC_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_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 };
 
 static const uint64_t xe_lpdp_modifier_order[] = { I915_FORMAT_MOD_4_TILED_MTL_RC_CCS,
+						   I915_FORMAT_MOD_4_TILED_MTL_MC_CCS,
 						   I915_FORMAT_MOD_4_TILED, I915_FORMAT_MOD_X_TILED,
 						   DRM_FORMAT_MOD_LINEAR };
 
@@ -112,12 +113,13 @@
 		0x46b3, 0x46c0, 0x46c1, 0x46c2, 0x46c3, 0x9A40, 0x9A49, 0x9A59, 0x9A60, 0x9A68,
 		0x9A70, 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8, 0x4905, 0x4906, 0x4907, 0x4908
 	};
-	const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8, 0x46AA,
-				      0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1, 0x46B2, 0x46B3,
-				      0x46C0, 0x46C1, 0x46C2, 0x46C3, 0x46D0, 0x46D1, 0x46D2,
-				      0x46D3, 0x46D4 };
+	const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8,
+				      0x46AA, 0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1,
+				      0x46B2, 0x46B3, 0x46C0, 0x46C1, 0x46C2, 0x46C3,
+				      0x46D0, 0x46D1, 0x46D2, 0x46D3, 0x46D4 };
 
-	const uint16_t rplp_ids[] = { 0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8, 0xA7A9, 0xA7AA, 0xA7AB, 0xA7AC, 0xA7AD };
+	const uint16_t rplp_ids[] = { 0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8,
+				      0xA7A9, 0xA7AA, 0xA7AB, 0xA7AC, 0xA7AD };
 
 	const uint16_t mtl_ids[] = { 0x7D40, 0x7D60, 0x7D45, 0x7D55, 0x7DD5 };
 
@@ -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,11 +600,13 @@
 		 * 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 &&
+	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;
@@ -656,6 +668,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 +795,68 @@
 		/* 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);
 	}
@@ -880,8 +922,7 @@
 		}
 	}
 
-	bo->meta.cached = (i915->has_llc || i915->is_mtl) &&
-			  !(bo->meta.use_flags & BO_USE_SCANOUT);
+	bo->meta.cached = (i915->has_llc || i915->is_mtl) && !(bo->meta.use_flags & BO_USE_SCANOUT);
 
 	return 0;
 }
@@ -933,7 +974,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) {
diff --git a/mediatek.c b/mediatek.c
index 6ebde6e..64661fb 100644
--- a/mediatek.c
+++ b/mediatek.c
@@ -39,7 +39,8 @@
     defined(MTK_MT8186) || \
     defined(MTK_MT8188G) || \
     defined(MTK_MT8192) || \
-    defined(MTK_MT8195)
+    defined(MTK_MT8195) || \
+    defined(MTK_MT8196)
 // clang-format on
 #define USE_NV12_FOR_HW_VIDEO_DECODING
 #define SUPPORT_FP16_AND_10BIT_ABGR
@@ -324,11 +325,25 @@
 #endif
 	}
 
-	gem_create.size = bo->meta.total_size;
-
 	/* For protected data buffer needs to be allocated from GEM */
-	if (bo->meta.use_flags & BO_USE_PROTECTED)
+	if (bo->meta.use_flags & BO_USE_PROTECTED) {
+		if (format == DRM_FORMAT_P010) {
+			/*
+			 * Adjust the size so we don't waste tons of space. This was allocated
+			 * with 16 bpp, but we only need 10 bpp. We can safely divide by 8 because
+			 * we are aligned at a multiple higher than that.
+			 */
+			bo->meta.strides[0] = bo->meta.strides[0] * 10 / 16;
+			bo->meta.strides[1] = bo->meta.strides[1] * 10 / 16;
+			bo->meta.sizes[0] = bo->meta.sizes[0] * 10 / 16;
+			bo->meta.sizes[1] = bo->meta.sizes[1] * 10 / 16;
+			bo->meta.offsets[1] = bo->meta.sizes[0];
+			bo->meta.total_size = bo->meta.total_size * 10 / 16;
+		}
 		gem_create.flags |= DRM_MTK_GEM_CREATE_ENCRYPTED;
+	}
+
+	gem_create.size = bo->meta.total_size;
 
 	ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_CREATE, &gem_create);
 	if (ret) {
diff --git a/msm.c b/msm.c
index d6f74cc..ee585c7 100644
--- a/msm.c
+++ b/msm.c
@@ -152,6 +152,13 @@
 
 		/* Calculate size and assign stride, size, offset to each plane based on format */
 		drv_bo_from_format(bo, stride, 1, alignh, bo->meta.format);
+		if (bo->meta.format == DRM_FORMAT_YVU420_ANDROID ||
+		    bo->meta.format == DRM_FORMAT_YVU420) {
+			const uint32_t u_size =
+			    drv_size_from_format(bo->meta.format, bo->meta.strides[2], alignh, 2);
+			const uint32_t padding = ALIGN(u_size, PLANE_SIZE_ALIGN) - u_size;
+			bo->meta.total_size += padding;
+		}
 
 		/* For all RGB UBWC formats */
 		if (bo->meta.tiling == MSM_UBWC_TILING) {
diff --git a/util.h b/util.h
index 8f8bb0d..aa1e79e 100644
--- a/util.h
+++ b/util.h
@@ -10,9 +10,9 @@
 #define MAX(A, B) ((A) > (B) ? (A) : (B))
 #define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))
 #define PUBLIC __attribute__((visibility("default")))
-#define ALIGN(A, B) (((A) + (B)-1) & ~((B)-1))
+#define ALIGN(A, B) (((A) + (B) - 1) & ~((B) - 1))
 #define IS_ALIGNED(A, B) (ALIGN((A), (B)) == (A))
-#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
 #define STRINGIZE_NO_EXPANSION(x) #x
 #define STRINGIZE(x) STRINGIZE_NO_EXPANSION(x)
 
diff --git a/virtgpu_virgl.c b/virtgpu_virgl.c
index 222703e..1af4bae 100644
--- a/virtgpu_virgl.c
+++ b/virtgpu_virgl.c
@@ -52,6 +52,11 @@
 	DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR16161616F
 };
 
+static const uint32_t depth_stencil_formats[] = {
+	DRM_FORMAT_DEPTH16, DRM_FORMAT_DEPTH24, DRM_FORMAT_DEPTH24_STENCIL8,
+	DRM_FORMAT_DEPTH32, DRM_FORMAT_DEPTH32_STENCIL8
+};
+
 extern struct virtgpu_param params[];
 
 struct virgl_blob_metadata_cache {
@@ -108,6 +113,16 @@
 	case DRM_FORMAT_YVU420:
 	case DRM_FORMAT_YVU420_ANDROID:
 		return VIRGL_FORMAT_YV12;
+	case DRM_FORMAT_DEPTH16:
+		return VIRGL_FORMAT_Z16_UNORM;
+	case DRM_FORMAT_DEPTH24:
+		return VIRGL_FORMAT_Z24X8_UNORM;
+	case DRM_FORMAT_DEPTH24_STENCIL8:
+		return VIRGL_FORMAT_Z24_UNORM_S8_UINT;
+	case DRM_FORMAT_DEPTH32:
+		return VIRGL_FORMAT_Z32_FLOAT;
+	case DRM_FORMAT_DEPTH32_STENCIL8:
+		return VIRGL_FORMAT_Z32_FLOAT_S8X24_UINT;
 	default:
 		drv_loge("Unhandled format:%d\n", drm_fourcc);
 		return 0;
@@ -639,6 +654,9 @@
 		virgl_add_combinations(drv, texture_source_formats,
 				       ARRAY_SIZE(texture_source_formats), &LINEAR_METADATA,
 				       BO_USE_TEXTURE_MASK);
+		virgl_add_combinations(drv, depth_stencil_formats,
+				       ARRAY_SIZE(depth_stencil_formats), &LINEAR_METADATA,
+				       BO_USE_RENDER_MASK | BO_USE_TEXTURE_MASK);
 		/* NV12 with scanout must flow through virgl_add_combination, so that the native
 		 * support is checked and scanout use_flag can be conditionally stripped. */
 		virgl_add_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA,