rockchip: add NV12 bo creation support

This patch does alignment if needed on the width and height, but does
not expose this change to the public facing gbm_bo. It is expected that
framebuffer creation in the kernel with do alignment such that
applications don't have to have platform specific knowledge of alignment
requirements.

TEST=nv12_test
BUG=chromium:607241

Change-Id: I6138afb56537f516fac038ff4db39593c623fccd
Reviewed-on: https://chromium-review.googlesource.com/341010
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
This commit is contained in:
Zach Reizner 2016-04-27 11:14:41 -07:00 committed by chrome-bot
parent 345278df00
commit 58080dfa64

View file

@ -6,6 +6,8 @@
#ifdef GBM_ROCKCHIP
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <xf86drm.h>
@ -13,33 +15,73 @@
#include "gbm_priv.h"
#include "helpers.h"
#include "util.h"
static int gbm_rockchip_bo_create(struct gbm_bo *bo,
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
size_t size;
struct drm_rockchip_gem_create gem_create;
int ret;
size_t plane;
bo->strides[0] = gbm_stride_from_format(format, width);
size = height * bo->strides[0];
memset(&gem_create, 0, sizeof(gem_create));
gem_create.size = size;
ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create);
if (ret) {
fprintf(stderr, "minigbm: DRM_IOCTL_ROCKCHIP_GEM_CREATE failed "
"(size=%zu)\n", size);
return ret;
switch (format) {
case GBM_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] = bo->offsets[1] = 0;
break;
case GBM_FORMAT_XRGB8888:
case GBM_FORMAT_ARGB8888:
case GBM_FORMAT_ABGR8888:
bo->strides[0] = gbm_stride_from_format(format, width);
bo->sizes[0] = height * bo->strides[0];
bo->offsets[0] = 0;
break;
default:
fprintf(stderr, "minigbm: rockchip: unsupported format %4.4s\n",
(char*)&format);
assert(0);
return -EINVAL;
}
bo->handles[0].u32 = gem_create.handle;
bo->sizes[0] = size;
bo->offsets[0] = 0;
int ret;
for (plane = 0; plane < bo->num_planes; plane++) {
size_t size = bo->sizes[plane];
struct drm_rockchip_gem_create gem_create;
memset(&gem_create, 0, sizeof(gem_create));
gem_create.size = size;
ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE,
&gem_create);
if (ret) {
fprintf(stderr, "minigbm: DRM_IOCTL_ROCKCHIP_GEM_CREATE failed "
"(size=%zu)\n", size);
goto cleanup_planes;
}
bo->handles[plane].u32 = gem_create.handle;
}
return 0;
cleanup_planes:
for ( ; plane != 0; plane--) {
struct drm_gem_close gem_close;
memset(&gem_close, 0, sizeof(gem_close));
gem_close.handle = bo->handles[plane - 1].u32;
int gem_close_ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_GEM_CLOSE,
&gem_close);
if (gem_close_ret) {
fprintf(stderr,
"minigbm: DRM_IOCTL_GEM_CLOSE failed: %d\n",
gem_close_ret);
}
}
return ret;
}
const struct gbm_driver gbm_driver_rockchip =
@ -53,6 +95,8 @@ const struct gbm_driver gbm_driver_rockchip =
{GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING},
{GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_LINEAR},
{GBM_FORMAT_ABGR8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING},
{GBM_FORMAT_NV12, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING},
{GBM_FORMAT_NV12, GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR},
}
};