From 42cc6d6c2a93f585daad4c70398edfd770578683 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Mon, 29 Aug 2016 18:19:19 -0700 Subject: [PATCH] minigbm: Added YV12 for Mali platforms MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Oak-cheets is using YV12 as it's Android flexible YUV format, so we need to support it. Additionally, we're trying to enable YV12 on Mali with EXT_image_dma_buf_import. Instead of having redundant switch statements in every driver, let's add a helper function to do this. BUG=chrome-os-partner:54632, b/29059119, chromium:616275 TEST=Ran plane_test, graphics_Gbm on veyron_minnie Change-Id: I4798225db809941367e58dde962576535b8d767c Reviewed-on: https://chromium-review.googlesource.com/377884 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- helpers.c | 37 +++++++++++++++++++++++++++++++++++++ helpers.h | 2 ++ i915.c | 26 ++++++-------------------- mediatek.c | 33 ++++++++++++++++++++++++--------- rockchip.c | 55 +++++++++++++++++-------------------------------------- 5 files changed, 86 insertions(+), 67 deletions(-) diff --git a/helpers.c b/helpers.c index b5eb732..14197e4 100644 --- a/helpers.c +++ b/helpers.c @@ -170,6 +170,43 @@ int drv_stride_from_format(uint32_t format, uint32_t width, size_t plane) return stride; } +/* + * This function fills in the buffer object given driver aligned dimensions + * and a format. This function assumes there is just one kernel buffer per + * buffer object. + */ +int drv_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, + drv_format_t format) +{ + + switch (format) { + case DRV_FORMAT_YVU420: + bo->strides[0] = drv_stride_from_format(format, width, 0); + bo->strides[1] = drv_stride_from_format(format, width, 1); + bo->strides[2] = drv_stride_from_format(format, width, 2); + 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; + case DRV_FORMAT_NV12: + bo->strides[0] = drv_stride_from_format(format, width, 0); + bo->strides[1] = drv_stride_from_format(format, width, 1); + bo->sizes[0] = height * bo->strides[0]; + bo->sizes[1] = height * bo->strides[1] / 2; + bo->offsets[0] = 0; + bo->offsets[1] = height * bo->strides[0]; + break; + default: + bo->strides[0] = drv_stride_from_format(format, width, 0); + bo->sizes[0] = height * bo->strides[0]; + bo->offsets[0] = 0; + } + + return 0; +} + int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) { diff --git a/helpers.h b/helpers.h index 923ce13..e9fc9d7 100644 --- a/helpers.h +++ b/helpers.h @@ -12,6 +12,8 @@ size_t drv_num_planes_from_format(uint32_t format); 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_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, + drv_format_t format); 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 e2646ad..a3f9084 100644 --- a/i915.c +++ b/i915.c @@ -127,7 +127,7 @@ static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, 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, plane; + size_t plane; int ret; if (flags & (DRV_BO_USE_CURSOR | DRV_BO_USE_LINEAR | @@ -142,34 +142,20 @@ static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, i915_align_dimensions(drv, tiling_mode, &width, &height, 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; - } + drv_bo_from_format(bo, width, height, format); 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)); - gem_create.size = size; + gem_create.size = bo->offsets[bo->num_planes - 1] + + bo->sizes[bo->num_planes - 1]; ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create); if (ret) { fprintf(stderr, "drv: DRM_IOCTL_I915_GEM_CREATE failed " - "(size=%zu)\n", size); + "(size=%llu)\n", gem_create.size); return ret; } @@ -219,7 +205,7 @@ static void *i915_bo_map(struct bo *bo) bo->drv->fd, gem_map.offset); } -drv_format_t i915_resolve_format(drv_format_t format) +static drv_format_t i915_resolve_format(drv_format_t format) { switch (format) { case DRV_FORMAT_FLEX_IMPLEMENTATION_DEFINED: diff --git a/mediatek.c b/mediatek.c index 5bc839f..2dd4114 100644 --- a/mediatek.c +++ b/mediatek.c @@ -18,26 +18,25 @@ static int mediatek_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) { - size_t size; - struct drm_mtk_gem_create gem_create; int ret; + size_t plane; + struct drm_mtk_gem_create gem_create; - bo->strides[0] = drv_stride_from_format(format, width, 0); - size = height * bo->strides[0]; + drv_bo_from_format(bo, width, height, format); memset(&gem_create, 0, sizeof(gem_create)); - gem_create.size = size; + gem_create.size = bo->offsets[bo->num_planes - 1] + + bo->sizes[bo->num_planes - 1]; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_MTK_GEM_CREATE, &gem_create); if (ret) { fprintf(stderr, "drv: DRM_IOCTL_MTK_GEM_CREATE failed " - "(size=%zu)\n", size); + "(size=%llu)\n", gem_create.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; return 0; } @@ -60,12 +59,26 @@ static void *mediatek_bo_map(struct bo *bo) bo->drv->fd, gem_map.offset); } +static drv_format_t mediatek_resolve_format(drv_format_t format) +{ + switch (format) { + case DRV_FORMAT_FLEX_IMPLEMENTATION_DEFINED: + /*HACK: See b/28671744 */ + return DRV_FORMAT_XBGR8888; + case DRV_FORMAT_FLEX_YCbCr_420_888: + return DRV_FORMAT_YVU420; + default: + return format; + } +} + const struct backend backend_mediatek = { .name = "mediatek", .bo_create = mediatek_bo_create, .bo_destroy = drv_gem_bo_destroy, .bo_map = mediatek_bo_map, + .resolve_format = mediatek_resolve_format, .format_list = { {DRV_FORMAT_XRGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | DRV_BO_USE_RENDERING | DRV_BO_USE_HW_TEXTURE | @@ -81,6 +94,8 @@ const struct backend backend_mediatek = {DRV_FORMAT_ARGB8888, DRV_BO_USE_SCANOUT | DRV_BO_USE_CURSOR | 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}, } }; diff --git a/rockchip.c b/rockchip.c index f5311c6..972f3ee 100644 --- a/rockchip.c +++ b/rockchip.c @@ -21,57 +21,34 @@ static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) { + int ret; size_t plane; + struct drm_rockchip_gem_create gem_create; - switch (format) { - case DRV_FORMAT_NV12: - width = ALIGN(width, 4); - height = ALIGN(height, 4); - bo->strides[0] = bo->strides[1] = width; - bo->sizes[0] = height * bo->strides[0]; - bo->sizes[1] = height * bo->strides[1] / 2; - bo->offsets[0] = 0; - bo->offsets[1] = height * bo->strides[0]; - break; - case DRV_FORMAT_XRGB8888: - case DRV_FORMAT_XBGR8888: - case DRV_FORMAT_ARGB8888: - case DRV_FORMAT_ABGR8888: - bo->strides[0] = drv_stride_from_format(format, width, 0); - bo->sizes[0] = height * bo->strides[0]; - bo->offsets[0] = 0; - break; - default: - fprintf(stderr, "drv: rockchip: unsupported format %4.4s\n", - (char*)&format); - assert(0); - return -EINVAL; + if (format == DRV_FORMAT_NV12) { + width = ALIGN(width, 4); + height = ALIGN(height, 4); } - int ret; - size_t size = 0; - - for (plane = 0; plane < bo->num_planes; plane++) - size += bo->sizes[plane]; - - struct drm_rockchip_gem_create gem_create; + drv_bo_from_format(bo, width, height, format); memset(&gem_create, 0, sizeof(gem_create)); - gem_create.size = size; + gem_create.size = bo->offsets[bo->num_planes - 1] + + bo->sizes[bo->num_planes - 1]; ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create); if (ret) { fprintf(stderr, "drv: DRM_IOCTL_ROCKCHIP_GEM_CREATE failed " - "(size=%zu)\n", size); - } - else { - for (plane = 0; plane < bo->num_planes; plane++) - bo->handles[plane].u32 = gem_create.handle; + "(size=%llu)\n", gem_create.size); + return ret; } - return ret; + for (plane = 0; plane < bo->num_planes; plane++) + bo->handles[plane].u32 = gem_create.handle; + + return 0; } static void *rockchip_bo_map(struct bo *bo) @@ -94,7 +71,7 @@ static void *rockchip_bo_map(struct bo *bo) bo->drv->fd, gem_map.offset); } -drv_format_t rockchip_resolve_format(drv_format_t format) +static drv_format_t rockchip_resolve_format(drv_format_t format) { switch (format) { case DRV_FORMAT_FLEX_IMPLEMENTATION_DEFINED: @@ -143,6 +120,8 @@ const struct backend backend_rockchip = DRV_BO_USE_SW_WRITE_RARELY}, {DRV_FORMAT_NV12, 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}, } }; -- 2.11.0