Support multi-plane buffers.
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>
diff --git a/exynos.c b/exynos.c
index b8cda49..bde6c11 100644
--- 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>
@@ -13,28 +15,53 @@
#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;
+ size_t plane;
- 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;
+ 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 @@
.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
--- 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 @@
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 @@
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 @@
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 @@
return NULL;
}
- bo->handle.u32 = prime_handle.handle;
+ bo->handles[0].u32 = prime_handle.handle;
return bo;
}
@@ -292,13 +302,13 @@
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 @@
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)
{
- int fd;
+ return gbm_bo_get_plane_fd(bo, 0);
+}
- if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm),
- gbm_bo_get_handle(bo).u32,
- DRM_CLOEXEC,
- &fd))
+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_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
--- a/gbm.h
+++ b/gbm.h
@@ -71,7 +71,7 @@
/** 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 @@
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);
diff --git a/gbm_priv.h b/gbm_priv.h
index 0e42934..5c35505 100644
--- a/gbm_priv.h
+++ b/gbm_priv.h
@@ -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_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 *);
diff --git a/helpers.c b/helpers.c
index 605a107..1ad10ce 100644
--- 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 @@
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 @@
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 @@
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 @@
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 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_gem_bo_destroy(struct gbm_bo *bo)
{
struct drm_gem_close gem_close;
- int ret;
+ int ret, error = 0;
+ size_t plane, i;
- memset(&gem_close, 0, sizeof(gem_close));
- gem_close.handle = bo->handle.u32;
+ 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;
- 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;
+ 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;
}
diff --git a/helpers.h b/helpers.h
index 06b59ba..3f8e5bf 100644
--- 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
--- a/i915.c
+++ b/i915.c
@@ -123,7 +123,7 @@
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 @@
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 @@
"(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,
diff --git a/mediatek.c b/mediatek.c
index e1d8f29..36eb6cd 100644
--- a/mediatek.c
+++ b/mediatek.c
@@ -17,10 +17,13 @@
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 @@
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/rockchip.c b/rockchip.c
index 0a721da..3df3595 100644
--- a/rockchip.c
+++ b/rockchip.c
@@ -17,10 +17,13 @@
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 @@
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
--- 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 @@
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 @@
* 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_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 @@
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
--- 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