OSDN Git Service

minigbm: Add YV12 for i915
authorGurchetan Singh <gurchetansingh@chromium.org>
Tue, 19 Jul 2016 22:52:33 +0000 (15:52 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Thu, 25 Aug 2016 08:44:57 +0000 (01:44 -0700)
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>
exynos.c
helpers.c
helpers.h
i915.c
mediatek.c
rockchip.c
tegra.c

index 3d58c02..2aef3e3 100644 (file)
--- a/exynos.c
+++ b/exynos.c
@@ -34,7 +34,7 @@ static int exynos_bo_create(struct bo *bo, uint32_t width, uint32_t height,
                bo->sizes[1] = bo->strides[1] * chroma_height + 64;
                bo->offsets[0] = bo->offsets[1] = 0;
        } else if (format == DRV_FORMAT_XRGB8888 || format == DRV_FORMAT_ARGB8888) {
-               bo->strides[0] = drv_stride_from_format(format, width);
+               bo->strides[0] = drv_stride_from_format(format, width, 0);
                bo->sizes[0] = height * bo->strides[0];
                bo->offsets[0] = 0;
        } else {
index 3e3e8b0..9336ced 100644 (file)
--- a/helpers.c
+++ b/helpers.c
@@ -70,15 +70,19 @@ size_t drv_num_planes_from_format(uint32_t format)
                        return 1;
                case DRV_FORMAT_NV12:
                        return 2;
+               case DRV_FORMAT_YVU420:
+                       return 3;
        }
 
        fprintf(stderr, "drv: UNKNOWN FORMAT %d\n", format);
        return 0;
 }
 
-int drv_bpp_from_format(uint32_t format)
+int drv_bpp_from_format(uint32_t format, size_t plane)
 {
-       switch(format)
+       assert(plane < drv_num_planes_from_format(format));
+
+       switch (format)
        {
                case DRV_FORMAT_C8:
                case DRV_FORMAT_R8:
@@ -87,7 +91,9 @@ int drv_bpp_from_format(uint32_t format)
                        return 8;
 
                case DRV_FORMAT_NV12:
-                       return 12;
+                       return (plane == 0) ? 8 : 4;
+               case DRV_FORMAT_YVU420:
+                       return (plane == 0) ? 8 : 2;
 
                case DRV_FORMAT_RG88:
                case DRV_FORMAT_GR88:
@@ -143,11 +149,27 @@ int drv_bpp_from_format(uint32_t format)
        return 0;
 }
 
-int drv_stride_from_format(uint32_t format, uint32_t width)
+/*
+ * This function returns the stride for a given format, width and plane.
+ */
+int drv_stride_from_format(uint32_t format, uint32_t width, size_t plane)
 {
-       /* Only single-plane formats are supported */
-       assert(drv_num_planes_from_format(format) == 1);
-       return DIV_ROUND_UP(width * drv_bpp_from_format(format), 8);
+       /* Get stride of the first plane */
+       int stride = width * DIV_ROUND_UP(drv_bpp_from_format(format, 0), 8);
+
+       /*
+        * Only downsample for certain multiplanar formats which are not
+        * interleaved and have horizontal subsampling.  Only formats supported
+        * by our drivers are listed here -- add more as needed.
+        */
+       if (plane != 0) {
+               switch (format) {
+                       case DRV_FORMAT_YVU420:
+                               stride = stride / 2;
+               }
+       }
+
+       return stride;
 }
 
 int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height,
@@ -162,7 +184,7 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height,
        memset(&create_dumb, 0, sizeof(create_dumb));
        create_dumb.height = height;
        create_dumb.width = width;
-       create_dumb.bpp = drv_bpp_from_format(format);
+       create_dumb.bpp = drv_bpp_from_format(format, 0);
        create_dumb.flags = 0;
 
        ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
index 7dfcc41..923ce13 100644 (file)
--- a/helpers.h
+++ b/helpers.h
@@ -10,8 +10,8 @@
 #include "drv.h"
 
 size_t drv_num_planes_from_format(uint32_t format);
-int drv_bpp_from_format(uint32_t format);
-int drv_stride_from_format(uint32_t format, uint32_t width);
+int drv_bpp_from_format(uint32_t format, size_t plane);
+int drv_stride_from_format(uint32_t format, uint32_t width, size_t plane);
 int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height,
                       uint32_t format, uint32_t flags);
 int drv_dumb_bo_destroy(struct bo *bo);
diff --git a/i915.c b/i915.c
index 4293fec..4942246 100644 (file)
--- a/i915.c
+++ b/i915.c
@@ -123,11 +123,11 @@ static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height,
                          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 @@ static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height,
 
        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 @@ static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height,
                                "(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 @@ drv_format_t i915_resolve_format(drv_format_t format)
                        /*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 @@ const struct backend backend_i915 =
                                      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},
        }
 };
 
index 600916d..5bc839f 100644 (file)
@@ -22,7 +22,7 @@ static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height,
        struct drm_mtk_gem_create gem_create;
        int ret;
 
-       bo->strides[0] = drv_stride_from_format(format, width);
+       bo->strides[0] = drv_stride_from_format(format, width, 0);
        size = height * bo->strides[0];
 
        memset(&gem_create, 0, sizeof(gem_create));
index 86a425a..33829b3 100644 (file)
@@ -36,7 +36,7 @@ static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height,
                case DRV_FORMAT_XRGB8888:
                case DRV_FORMAT_ARGB8888:
                case DRV_FORMAT_ABGR8888:
-                       bo->strides[0] = drv_stride_from_format(format, width);
+                       bo->strides[0] = drv_stride_from_format(format, width, 0);
                        bo->sizes[0] = height * bo->strides[0];
                        bo->offsets[0] = 0;
                        break;
diff --git a/tegra.c b/tegra.c
index cafd000..d0ccc4d 100644 (file)
--- a/tegra.c
+++ b/tegra.c
@@ -56,7 +56,7 @@ static void compute_layout_blocklinear(int width, int height, int format,
                                       uint32_t *block_height_log2,
                                       uint32_t *stride, uint32_t *size)
 {
-       int pitch = drv_stride_from_format(format, width);
+       int pitch = drv_stride_from_format(format, width, 0);
 
        /* Align to blocklinear blocks. */
        pitch = ALIGN(pitch, NV_BLOCKLINEAR_GOB_WIDTH);
@@ -83,7 +83,7 @@ static void compute_layout_blocklinear(int width, int height, int format,
 static void compute_layout_linear(int width, int height, int format,
                                  uint32_t *stride, uint32_t *size)
 {
-       *stride = drv_stride_from_format(format, width);
+       *stride = drv_stride_from_format(format, width, 0);
        *size = *stride * height;
 }