minigbm: Add YV12 for i915

At the moment, the ArcCodec produces YV12 on Intel.  The gralloc
module should support it, atleast temporarily until UYVY hardware
overlays are enabled on CrOS.

TEST=ran graphics_Gbm, tested Chrome boots on Cyan
BUG=b/29335168, chromium:616275
CQ-DEPEND=CL:372359

Change-Id: I27c888d3467aa89e8ca48b22523cbc76973aa314
Reviewed-on: https://chromium-review.googlesource.com/373048
Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
diff --git a/i915.c b/i915.c
index 4293fec..4942246 100644
--- a/i915.c
+++ b/i915.c
@@ -123,11 +123,11 @@
 			  uint32_t format, uint32_t flags)
 {
 	struct driver *drv = bo->drv;
-	int bpp = drv_stride_from_format(format, 1);
+	int bpp = drv_stride_from_format(format, 1, 0);
 	struct drm_i915_gem_create gem_create;
 	struct drm_i915_gem_set_tiling gem_set_tiling;
 	uint32_t tiling_mode = I915_TILING_NONE;
-	size_t size;
+	size_t size, plane;
 	int ret;
 
 	if (flags & (DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR |
@@ -142,13 +142,28 @@
 
 	i915_align_dimensions(drv, tiling_mode, &width, &height, bpp);
 
-	bo->strides[0] = width * bpp;
+	switch (format) {
+		case DRV_FORMAT_YVU420:
+			bo->strides[0] = drv_stride_from_format(format, width, 0);
+			bo->strides[1] = bo->strides[2] = drv_stride_from_format(format, width, 1);
+			bo->sizes[0] = height * bo->strides[0];
+			bo->sizes[1] = bo->sizes[2] = (height / 2) * bo->strides[1];
+			bo->offsets[0] = 0;
+			bo->offsets[1] = bo->sizes[0];
+			bo->offsets[2] = bo->offsets[1] + bo->sizes[1];
+			break;
+		default:
+			bo->strides[0] = drv_stride_from_format(format, width, 0);
+			bo->sizes[0] = height * bo->strides[0];
+			bo->offsets[0] = 0;
+	}
 
 	if (!i915_verify_dimensions(drv, bo->strides[0], height))
 		return EINVAL;
 
+	size = bo->offsets[bo->num_planes - 1] + bo->sizes[bo->num_planes - 1];
+
 	memset(&gem_create, 0, sizeof(gem_create));
-	size = width * height * bpp;
 	gem_create.size = size;
 
 	ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
@@ -157,9 +172,9 @@
 				"(size=%zu)\n", size);
 		return ret;
 	}
-	bo->handles[0].u32 = gem_create.handle;
-	bo->sizes[0] = size;
-	bo->offsets[0] = 0;
+
+	for (plane = 0; plane < bo->num_planes; plane++)
+		bo->handles[plane].u32 = gem_create.handle;
 
 	memset(&gem_set_tiling, 0, sizeof(gem_set_tiling));
 	do {
@@ -211,10 +226,6 @@
 			/*HACK: See b/28671744 */
 			return DRV_FORMAT_XBGR8888;
 		case DRV_FORMAT_FLEX_YCbCr_420_888:
-			/*
-			 * TODO(gurchetansingh) Implement YV12 with no tiling
-			 * on Intel. See b/29335168
-			 */
 			return DRV_FORMAT_YVU420;
 		default:
 			return format;
@@ -283,6 +294,8 @@
 				      DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
 		{DRV_FORMAT_GR88,     DRV_BO_USE_SCANOUT | DRV_BO_USE_LINEAR |
 				      DRV_BO_USE_SW_READ_OFTEN | DRV_BO_USE_SW_WRITE_OFTEN},
+		{DRV_FORMAT_YVU420,   DRV_BO_USE_LINEAR | DRV_BO_USE_SW_READ_OFTEN |
+				      DRV_BO_USE_SW_WRITE_OFTEN},
 	}
 };