OSDN Git Service

Support multi-plane buffers.
authorYuly Novikov <ynovikov@chromium.org>
Wed, 9 Dec 2015 03:48:29 +0000 (22:48 -0500)
committerchrome-bot <chrome-bot@chromium.org>
Sat, 23 Jan 2016 14:40:51 +0000 (06:40 -0800)
Enable NV12 format on Exynos.

BUG=chromium:368775
TEST=HW video overlay works on snow and peach_pi

Change-Id: Ia149618fa086b9ba3ef998149c3557052833e33b
Signed-off-by: Yuly Novikov <ynovikov@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/318550
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
exynos.c
gbm.c
gbm.h
gbm_priv.h
helpers.c
helpers.h
i915.c
mediatek.c
rockchip.c
tegra.c
util.h

index b8cda49..bde6c11 100644 (file)
--- a/exynos.c
+++ b/exynos.c
@@ -6,6 +6,8 @@
 
 #ifdef GBM_EXYNOS
 
+#include <assert.h>
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <xf86drm.h>
 
 #include "gbm_priv.h"
 #include "helpers.h"
+#include "util.h"
 
 int gbm_exynos_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
                         uint32_t format, uint32_t flags)
 {
-       size_t size = width * height * gbm_bytes_from_format(format);
-       struct drm_exynos_gem_create gem_create;
-       int ret;
-
-       memset(&gem_create, 0, sizeof(gem_create));
-       gem_create.size = size;
-       gem_create.flags = EXYNOS_BO_NONCONTIG;
-
-       ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &gem_create);
-       if (ret) {
-               fprintf(stderr, "minigbm: DRM_IOCTL_EXYNOS_GEM_CREATE failed "
-                               "(size=%zu)\n", size);
-               return ret;
+       size_t plane;
+
+       if (format == GBM_FORMAT_NV12) {
+               uint32_t chroma_height;
+               /* V4L2 s5p-mfc requires width to be 16 byte aligned and height 32. */
+               width = ALIGN(width, 16);
+               height = ALIGN(height, 32);
+               chroma_height = ALIGN(height / 2, 32);
+               bo->strides[0] = bo->strides[1] = width;
+               /* MFC v8+ requires 64 byte padding in the end of luma and chroma buffers. */
+               bo->sizes[0] = bo->strides[0] * height + 64;
+               bo->sizes[1] = bo->strides[1] * chroma_height + 64;
+               bo->offsets[0] = bo->offsets[1] = 0;
+       } else if (format == GBM_FORMAT_XRGB8888 || format == GBM_FORMAT_ARGB8888 ||
+                       format == GBM_BO_FORMAT_XRGB8888 || format == GBM_BO_FORMAT_ARGB8888 ) {
+               bo->strides[0] = gbm_stride_from_format(format, width);
+               bo->sizes[0] = height * bo->strides[0];
+               bo->offsets[0] = 0;
+       } else {
+               fprintf(stderr, "minigbm: unsupported format %X\n", format);
+               assert(0);
+               return -EINVAL;
        }
 
-       bo->handle.u32 = gem_create.handle;
-       bo->size = size;
-       bo->stride = width * gbm_bytes_from_format(format);
+       for (plane = 0; plane < bo->num_planes; plane++) {
+               size_t size = bo->sizes[plane];
+               struct drm_exynos_gem_create gem_create;
+               int ret;
+
+               memset(&gem_create, 0, sizeof(gem_create));
+               gem_create.size = size;
+               gem_create.flags = EXYNOS_BO_NONCONTIG;
+
+               ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &gem_create);
+               if (ret) {
+                       fprintf(stderr, "minigbm: DRM_IOCTL_EXYNOS_GEM_CREATE failed "
+                                       "(size=%zu)\n", size);
+                       return ret;
+               }
+
+               bo->handles[plane].u32 = gem_create.handle;
+       }
 
        return 0;
 }
@@ -47,6 +74,7 @@ const struct gbm_driver gbm_driver_exynos =
        .format_list = {
                {GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
                {GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
+               {GBM_FORMAT_NV12, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
        }
 };
 
diff --git a/gbm.c b/gbm.c
index ad031a4..628ed3f 100644 (file)
--- a/gbm.c
+++ b/gbm.c
@@ -4,6 +4,7 @@
  * found in the LICENSE file.
  */
 
+#include <assert.h>
 #include <fcntl.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -189,22 +190,23 @@ PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface,
 
 static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm,
                                 uint32_t width, uint32_t height,
-                                uint32_t format, uint32_t stride)
+                                uint32_t format)
 {
        struct gbm_bo *bo;
 
-       bo = (struct gbm_bo*) malloc(sizeof(*bo));
+       bo = (struct gbm_bo*) calloc(1, sizeof(*bo));
        if (!bo)
                return NULL;
 
        bo->gbm = gbm;
        bo->width = width;
        bo->height = height;
-       bo->stride = stride;
        bo->format = format;
-       bo->handle.u32 = 0;
-       bo->destroy_user_data = NULL;
-       bo->user_data = NULL;
+       bo->num_planes = gbm_num_planes_from_format(format);
+       if (!bo->num_planes) {
+               free(bo);
+               return NULL;
+       }
 
        return bo;
 }
@@ -216,8 +218,10 @@ PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width,
        struct gbm_bo *bo;
        int ret;
 
-       bo = gbm_bo_new(gbm, width, height, format,
-                       width * gbm_bytes_from_format(format));
+       if (!gbm_device_is_format_supported(gbm, format, 0))
+               return NULL;
+
+       bo = gbm_bo_new(gbm, width, height, format);
        if (!bo)
                return NULL;
 
@@ -257,8 +261,14 @@ gbm_bo_import(struct gbm_device *gbm, uint32_t type,
        if (!gbm_device_is_format_supported(gbm, fd_data->format, usage))
                return NULL;
 
-       bo = gbm_bo_new(gbm, fd_data->width, fd_data->height, fd_data->format,
-                       fd_data->stride);
+       /* This function can support only single plane formats. */
+       /* If multi-plane import is desired, new function should be added. */
+       if (gbm_num_planes_from_format(fd_data->format) != 1)
+               return NULL;
+
+       bo = gbm_bo_new(gbm, fd_data->width, fd_data->height, fd_data->format);
+       bo->strides[0] = fd_data->stride;
+
        if (!bo)
                return NULL;
 
@@ -272,7 +282,7 @@ gbm_bo_import(struct gbm_device *gbm, uint32_t type,
                return NULL;
        }
 
-       bo->handle.u32 = prime_handle.handle;
+       bo->handles[0].u32 = prime_handle.handle;
 
        return bo;
 }
@@ -292,13 +302,13 @@ gbm_bo_get_height(struct gbm_bo *bo)
 PUBLIC uint32_t
 gbm_bo_get_stride(struct gbm_bo *bo)
 {
-       return bo->stride;
+       return gbm_bo_get_plane_stride(bo, 0);
 }
 
 PUBLIC uint32_t
 gbm_bo_get_stride_or_tiling(struct gbm_bo *bo)
 {
-       return bo->tiling ? bo->tiling : bo->stride;
+       return bo->tiling ? bo->tiling : gbm_bo_get_stride(bo);
 }
 
 PUBLIC uint32_t
@@ -316,23 +326,65 @@ gbm_bo_get_device(struct gbm_bo *bo)
 PUBLIC union gbm_bo_handle
 gbm_bo_get_handle(struct gbm_bo *bo)
 {
-       return bo->handle;
+       return gbm_bo_get_plane_handle(bo, 0);
 }
 
 PUBLIC int
 gbm_bo_get_fd(struct gbm_bo *bo)
 {
+       return gbm_bo_get_plane_fd(bo, 0);
+}
+
+PUBLIC size_t
+gbm_bo_get_num_planes(struct gbm_bo *bo)
+{
+       return bo->num_planes;
+}
+
+PUBLIC union gbm_bo_handle
+gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane)
+{
+       assert(plane < bo->num_planes);
+       return bo->handles[plane];
+}
+
+PUBLIC int
+gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane)
+{
        int fd;
+       assert(plane < bo->num_planes);
 
-       if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm),
-                               gbm_bo_get_handle(bo).u32,
-                               DRM_CLOEXEC,
-                               &fd))
+       if (drmPrimeHandleToFD(
+                       gbm_device_get_fd(bo->gbm),
+                       gbm_bo_get_plane_handle(bo, plane).u32,
+                       DRM_CLOEXEC,
+                       &fd))
                return -1;
        else
                return fd;
 }
 
+PUBLIC uint32_t
+gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane)
+{
+       assert(plane < bo->num_planes);
+       return bo->offsets[plane];
+}
+
+PUBLIC uint32_t
+gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane)
+{
+       assert(plane < bo->num_planes);
+       return bo->sizes[plane];
+}
+
+PUBLIC uint32_t
+gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane)
+{
+       assert(plane < bo->num_planes);
+       return bo->strides[plane];
+}
+
 PUBLIC void
 gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
                     void (*destroy_user_data)(struct gbm_bo *, void *))
diff --git a/gbm.h b/gbm.h
index 094d746..fbb8cbc 100644 (file)
--- a/gbm.h
+++ b/gbm.h
@@ -71,7 +71,7 @@ union gbm_bo_handle {
 /** Format of the allocated buffer */
 enum gbm_bo_format {
    /** RGB with 8 bits per channel in a 32 bit value */
-   GBM_BO_FORMAT_XRGB8888, 
+   GBM_BO_FORMAT_XRGB8888,
    /** ARGB with 8 bits per channel in a 32 bit value */
    GBM_BO_FORMAT_ARGB8888
 };
@@ -273,6 +273,24 @@ gbm_bo_get_handle(struct gbm_bo *bo);
 int
 gbm_bo_get_fd(struct gbm_bo *bo);
 
+size_t
+gbm_bo_get_num_planes(struct gbm_bo *bo);
+
+union gbm_bo_handle
+gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane);
+
+int
+gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane);
+
+uint32_t
+gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane);
+
+uint32_t
+gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane);
+
+uint32_t
+gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane);
+
 int
 gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count);
 
index 0e42934..5c35505 100644 (file)
@@ -12,6 +12,8 @@
 #include <stdlib.h>
 #include "gbm.h"
 
+#define GBM_MAX_PLANES 4
+
 struct gbm_device
 {
        int fd;
@@ -28,11 +30,13 @@ struct gbm_bo
        struct gbm_device *gbm;
        uint32_t width;
        uint32_t height;
-       uint32_t size;
-       uint32_t stride;
        uint32_t format;
        uint32_t tiling;
-       union gbm_bo_handle handle;
+       size_t num_planes;
+       union gbm_bo_handle handles[GBM_MAX_PLANES];
+       uint32_t offsets[GBM_MAX_PLANES];
+       uint32_t sizes[GBM_MAX_PLANES];
+       uint32_t strides[GBM_MAX_PLANES];
        void *priv;
        void *user_data;
        void (*destroy_user_data)(struct gbm_bo *, void *);
index 605a107..1ad10ce 100644 (file)
--- a/helpers.c
+++ b/helpers.c
@@ -4,13 +4,78 @@
  * found in the LICENSE file.
  */
 
-#include <stdlib.h>
+#include <assert.h>
+#include <stdbool.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <xf86drm.h>
 
 #include "gbm_priv.h"
 #include "helpers.h"
+#include "util.h"
+
+size_t gbm_num_planes_from_format(uint32_t format)
+{
+       if (format == GBM_BO_FORMAT_XRGB8888)
+               format = GBM_FORMAT_XRGB8888;
+       if (format == GBM_BO_FORMAT_ARGB8888)
+               format = GBM_FORMAT_ARGB8888;
+
+       switch(format)
+       {
+               case GBM_FORMAT_C8:
+               case GBM_FORMAT_RGB332:
+               case GBM_FORMAT_BGR233:
+               case GBM_FORMAT_XRGB4444:
+               case GBM_FORMAT_XBGR4444:
+               case GBM_FORMAT_RGBX4444:
+               case GBM_FORMAT_BGRX4444:
+               case GBM_FORMAT_ARGB4444:
+               case GBM_FORMAT_ABGR4444:
+               case GBM_FORMAT_RGBA4444:
+               case GBM_FORMAT_BGRA4444:
+               case GBM_FORMAT_XRGB1555:
+               case GBM_FORMAT_XBGR1555:
+               case GBM_FORMAT_RGBX5551:
+               case GBM_FORMAT_BGRX5551:
+               case GBM_FORMAT_ARGB1555:
+               case GBM_FORMAT_ABGR1555:
+               case GBM_FORMAT_RGBA5551:
+               case GBM_FORMAT_BGRA5551:
+               case GBM_FORMAT_RGB565:
+               case GBM_FORMAT_BGR565:
+               case GBM_FORMAT_YUYV:
+               case GBM_FORMAT_YVYU:
+               case GBM_FORMAT_UYVY:
+               case GBM_FORMAT_VYUY:
+               case GBM_FORMAT_RGB888:
+               case GBM_FORMAT_BGR888:
+               case GBM_FORMAT_XRGB8888:
+               case GBM_FORMAT_XBGR8888:
+               case GBM_FORMAT_RGBX8888:
+               case GBM_FORMAT_BGRX8888:
+               case GBM_FORMAT_ARGB8888:
+               case GBM_FORMAT_ABGR8888:
+               case GBM_FORMAT_RGBA8888:
+               case GBM_FORMAT_BGRA8888:
+               case GBM_FORMAT_XRGB2101010:
+               case GBM_FORMAT_XBGR2101010:
+               case GBM_FORMAT_RGBX1010102:
+               case GBM_FORMAT_BGRX1010102:
+               case GBM_FORMAT_ARGB2101010:
+               case GBM_FORMAT_ABGR2101010:
+               case GBM_FORMAT_RGBA1010102:
+               case GBM_FORMAT_BGRA1010102:
+               case GBM_FORMAT_AYUV:
+                       return 1;
+               case GBM_FORMAT_NV12:
+                       return 2;
+       }
+
+       fprintf(stderr, "minigbm: UNKNOWN FORMAT %d\n", format);
+       return 0;
+}
 
 int gbm_bpp_from_format(uint32_t format)
 {
@@ -26,6 +91,9 @@ int gbm_bpp_from_format(uint32_t format)
                case GBM_FORMAT_BGR233:
                        return 8;
 
+               case GBM_FORMAT_NV12:
+                       return 12;
+
                case GBM_FORMAT_XRGB4444:
                case GBM_FORMAT_XBGR4444:
                case GBM_FORMAT_RGBX4444:
@@ -74,13 +142,15 @@ int gbm_bpp_from_format(uint32_t format)
                        return 32;
        }
 
-       printf("UNKNOWN FORMAT %d\n", format);
+       fprintf(stderr, "minigbm: UNKNOWN FORMAT %d\n", format);
        return 0;
 }
 
-int gbm_bytes_from_format(uint32_t format)
+int gbm_stride_from_format(uint32_t format, uint32_t width)
 {
-       return gbm_bpp_from_format(format) / 8;
+       /* Only single-plane formats are supported */
+       assert(gbm_num_planes_from_format(format) == 1);
+       return DIV_ROUND_UP(width * gbm_bpp_from_format(format), 8);
 }
 
 int gbm_is_format_supported(struct gbm_bo *bo)
@@ -94,6 +164,9 @@ int gbm_dumb_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
        struct drm_mode_create_dumb create_dumb;
        int ret;
 
+       /* Only single-plane formats are supported */
+       assert(gbm_num_planes_from_format(format) == 1);
+
        memset(&create_dumb, 0, sizeof(create_dumb));
        create_dumb.height = height;
        create_dumb.width = width;
@@ -102,14 +175,14 @@ int gbm_dumb_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
 
        ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
        if (ret) {
-               fprintf(stderr, "minigbm: DRM_IOCTL_MODE_CREATE_DUMB failed "
-                               "(handle=%x)\n", bo->handle.u32);
+               fprintf(stderr, "minigbm: DRM_IOCTL_MODE_CREATE_DUMB failed\n");
                return ret;
        }
 
-       bo->handle.u32 = create_dumb.handle;
-       bo->size = create_dumb.size;
-       bo->stride = create_dumb.pitch;
+       bo->handles[0].u32 = create_dumb.handle;
+       bo->offsets[0] = 0;
+       bo->sizes[0] = create_dumb.size;
+       bo->strides[0] = create_dumb.pitch;
 
        return 0;
 }
@@ -120,12 +193,12 @@ int gbm_dumb_bo_destroy(struct gbm_bo *bo)
        int ret;
 
        memset(&destroy_dumb, 0, sizeof(destroy_dumb));
-       destroy_dumb.handle = bo->handle.u32;
+       destroy_dumb.handle = bo->handles[0].u32;
 
        ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
        if (ret) {
                fprintf(stderr, "minigbm: DRM_IOCTL_MODE_DESTROY_DUMB failed "
-                               "(handle=%x)\n", bo->handle.u32);
+                               "(handle=%x)\n", bo->handles[0].u32);
                return ret;
        }
 
@@ -135,17 +208,28 @@ int gbm_dumb_bo_destroy(struct gbm_bo *bo)
 int gbm_gem_bo_destroy(struct gbm_bo *bo)
 {
        struct drm_gem_close gem_close;
-       int ret;
-
-       memset(&gem_close, 0, sizeof(gem_close));
-       gem_close.handle = bo->handle.u32;
-
-       ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
-       if (ret) {
-               fprintf(stderr, "minigbm: DRM_IOCTL_GEM_CLOSE failed "
-                               "(handle=%x)\n", bo->handle.u32);
-               return ret;
+       int ret, error = 0;
+       size_t plane, i;
+
+       for (plane = 0; plane < bo->num_planes; plane++) {
+               bool already_closed = false;
+               for (i = 1; i < plane && !already_closed; i++)
+                       if (bo->handles[i-1].u32 == bo->handles[plane].u32)
+                               already_closed = true;
+               if (already_closed)
+                       continue;
+
+               memset(&gem_close, 0, sizeof(gem_close));
+               gem_close.handle = bo->handles[plane].u32;
+
+               ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+               if (ret) {
+                       fprintf(stderr, "minigbm: DRM_IOCTL_GEM_CLOSE failed "
+                                       "(handle=%x) error %d\n",
+                                       bo->handles[plane].u32, ret);
+                       error = ret;
+               }
        }
 
-       return 0;
+       return error;
 }
index 06b59ba..3f8e5bf 100644 (file)
--- a/helpers.h
+++ b/helpers.h
@@ -7,8 +7,9 @@
 #ifndef HELPERS_H
 #define HELPERS_H
 
+size_t gbm_num_planes_from_format(uint32_t format);
 int gbm_bpp_from_format(uint32_t format);
-int gbm_bytes_from_format(uint32_t format);
+int gbm_stride_from_format(uint32_t format, uint32_t width);
 int gbm_is_format_supported(struct gbm_bo *bo);
 int gbm_dumb_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
                       uint32_t format, uint32_t flags);
diff --git a/i915.c b/i915.c
index 6e2436b..74269ef 100644 (file)
--- a/i915.c
+++ b/i915.c
@@ -123,7 +123,7 @@ int gbm_i915_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
                       uint32_t format, uint32_t flags)
 {
        struct gbm_device *gbm = bo->gbm;
-       int bpp = gbm_bytes_from_format(format);
+       int bpp = gbm_stride_from_format(format, 1);
        struct drm_i915_gem_create gem_create;
        struct drm_i915_gem_set_tiling gem_set_tiling;
        uint32_t tiling_mode = I915_TILING_NONE;
@@ -139,9 +139,9 @@ int gbm_i915_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
 
        i915_align_dimensions(gbm, tiling_mode, &width, &height, bpp);
 
-       bo->stride = width * bpp;
+       bo->strides[0] = width * bpp;
 
-       if (!i915_verify_dimensions(gbm, bo->stride, height))
+       if (!i915_verify_dimensions(gbm, bo->strides[0], height))
                return EINVAL;
 
        memset(&gem_create, 0, sizeof(gem_create));
@@ -154,21 +154,22 @@ int gbm_i915_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
                                "(size=%zu)\n", size);
                return ret;
        }
-       bo->handle.u32 = gem_create.handle;
-       bo->size = size;
+       bo->handles[0].u32 = gem_create.handle;
+       bo->sizes[0] = size;
+       bo->offsets[0] = 0;
 
        memset(&gem_set_tiling, 0, sizeof(gem_set_tiling));
        do {
-               gem_set_tiling.handle = bo->handle.u32;
+               gem_set_tiling.handle = bo->handles[0].u32;
                gem_set_tiling.tiling_mode = tiling_mode;
-               gem_set_tiling.stride = bo->stride;
+               gem_set_tiling.stride = bo->strides[0];
                ret = drmIoctl(gbm->fd, DRM_IOCTL_I915_GEM_SET_TILING,
                               &gem_set_tiling);
        } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
 
        if (ret == -1) {
                struct drm_gem_close gem_close;
-               gem_close.handle = bo->handle.u32;
+               gem_close.handle = bo->handles[0].u32;
                fprintf(stderr, "minigbm: DRM_IOCTL_I915_GEM_SET_TILING failed "
                                "errno=%x (handle=%x, tiling=%x, stride=%x)\n",
                                errno,
index e1d8f29..36eb6cd 100644 (file)
 int gbm_mediatek_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
                           uint32_t format, uint32_t flags)
 {
-       size_t size = width * height * gbm_bytes_from_format(format);
+       size_t size;
        struct drm_mtk_gem_create gem_create;
        int ret;
 
+       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;
 
@@ -31,9 +34,9 @@ int gbm_mediatek_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
                return ret;
        }
 
-       bo->handle.u32 = gem_create.handle;
-       bo->size = size;
-       bo->stride = width * gbm_bytes_from_format(format);
+       bo->handles[0].u32 = gem_create.handle;
+       bo->sizes[0] = size;
+       bo->offsets[0] = 0;
 
        return 0;
 }
index 0a721da..3df3595 100644 (file)
 int gbm_rockchip_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
                           uint32_t format, uint32_t flags)
 {
-       size_t size = width * height * gbm_bytes_from_format(format);
+       size_t size;
        struct drm_rockchip_gem_create gem_create;
        int ret;
 
+       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;
 
@@ -31,9 +34,9 @@ int gbm_rockchip_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height,
                return ret;
        }
 
-       bo->handle.u32 = gem_create.handle;
-       bo->size = size;
-       bo->stride = width * gbm_bytes_from_format(format);
+       bo->handles[0].u32 = gem_create.handle;
+       bo->sizes[0] = size;
+       bo->offsets[0] = 0;
 
        return 0;
 }
diff --git a/tegra.c b/tegra.c
index 4ffe037..1cfdda7 100644 (file)
--- a/tegra.c
+++ b/tegra.c
@@ -13,6 +13,7 @@
 
 #include "gbm_priv.h"
 #include "helpers.h"
+#include "util.h"
 
 /*
  * GOB (Group Of Bytes) is the basic unit of the blocklinear layout.
@@ -48,26 +49,21 @@ static int compute_block_height_log2(int height)
        return block_height_log2;
 }
 
-static inline uint32_t align_up(uint32_t value, uint32_t alignment)
-{
-       return (value + (alignment-1)) & ~(alignment-1);
-}
-
 static void compute_layout_blocklinear(int width, int height, int format,
                                       enum nv_mem_kind *kind,
                                       uint32_t *block_height_log2,
                                       uint32_t *stride, uint32_t *size)
 {
-       int pitch = width * gbm_bytes_from_format(format);
+       int pitch = gbm_stride_from_format(format, width);
 
        /* Align to blocklinear blocks. */
-       pitch = align_up(pitch, NV_BLOCKLINEAR_GOB_WIDTH);
+       pitch = ALIGN(pitch, NV_BLOCKLINEAR_GOB_WIDTH);
 
        /* Compute padded height. */
        *block_height_log2 = compute_block_height_log2(height);
        int block_height = 1 << *block_height_log2;
        int padded_height =
-               align_up(height, NV_BLOCKLINEAR_GOB_HEIGHT * block_height);
+               ALIGN(height, NV_BLOCKLINEAR_GOB_HEIGHT * block_height);
 
        int bytes = pitch * padded_height;
 
@@ -75,7 +71,7 @@ static void compute_layout_blocklinear(int width, int height, int format,
         * This will reduce the required page table size (see discussion in NV
         * bug 1321091), and also acts as a WAR for NV bug 1325421.
         */
-       bytes = align_up(bytes, NV_PREFERRED_PAGE_SIZE);
+       bytes = ALIGN(bytes, NV_PREFERRED_PAGE_SIZE);
 
        *kind = NV_MEM_KIND_GENERIC_16Bx2;
        *stride = pitch;
@@ -85,7 +81,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 = width * gbm_bytes_from_format(format);
+       *stride = gbm_stride_from_format(format, width);
        *size = *stride * height;
 }
 
@@ -114,15 +110,16 @@ static int gbm_tegra_bo_create(struct gbm_bo *bo, uint32_t width,
                return ret;
        }
 
-       bo->handle.u32 = gem_create.handle;
-       bo->size = size;
-       bo->stride = stride;
+       bo->handles[0].u32 = gem_create.handle;
+       bo->offsets[0] = 0;
+       bo->sizes[0] = size;
+       bo->strides[0] = stride;
 
        if (kind != NV_MEM_KIND_PITCH) {
                struct drm_tegra_gem_set_tiling gem_tile;
 
                memset(&gem_tile, 0, sizeof(gem_tile));
-               gem_tile.handle = bo->handle.u32;
+               gem_tile.handle = bo->handles[0].u32;
                gem_tile.mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK;
                gem_tile.value = block_height_log2;
 
diff --git a/util.h b/util.h
index 197312a..9606336 100644 (file)
--- a/util.h
+++ b/util.h
@@ -11,5 +11,6 @@
 #define ARRAY_SIZE(A) (sizeof(A)/sizeof(*(A)))
 #define PUBLIC __attribute__((visibility("default")))
 #define ALIGN(A, B) (((A) + (B) - 1) / (B) * (B))
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
 
 #endif